cziegeler 2002/06/24 03:44:33
Modified: src/webapp sitemap.xmap
src/webapp/docs/samples sample-apps.xml
Added: src/webapp/samples/mod-db database.xml edit-groups.xsp
schema.sql sitemap.xmap stupid.xsl user-list.xsp
src/webapp/samples/protected sitemap.xmap
src/webapp/samples/protected/descriptors auth.xml params.xml
src/webapp/samples/protected/docs login.xml protected.xsp
src/webapp/samples/protected/stylesheets error2html.xsl
simple-page2html.xsl
Removed: src/webapp/mod-db database.xml edit-groups.xsp schema.sql
sitemap.xmap stupid.xsl user-list.xsp
src/webapp/protected sitemap.xmap
src/webapp/protected/descriptors auth.xml params.xml
src/webapp/protected/docs login.xml protected.xsp
src/webapp/protected/stylesheets error2html.xsl
simple-page2html.xsl
Log:
Moved protected and mod-db sample into samples area
Revision Changes Path
1.62 +0 -10 xml-cocoon2/src/webapp/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/sitemap.xmap,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- sitemap.xmap 3 Jun 2002 09:17:34 -0000 1.61
+++ sitemap.xmap 24 Jun 2002 10:44:32 -0000 1.62
@@ -605,16 +605,6 @@
<!-- pipeline mounting samples sitemaps -->
<map:pipeline>
- <!-- protected webapp example pipeline -->
- <map:match pattern="protected/**">
- <map:mount check-reload="yes" src="protected/" uri-prefix="protected"/>
- </map:match>
-
- <!-- mod-db webapp example pipeline -->
- <map:match pattern="mod-db/**">
- <map:mount check-reload="yes" src="mod-db/" uri-prefix="mod-db"/>
- </map:match>
-
<!-- mount other sample pages -->
<map:match pattern="samples/**">
<map:mount check-reload="yes" src="samples/" uri-prefix="samples"/>
1.6 +3 -3 xml-cocoon2/src/webapp/docs/samples/sample-apps.xml
Index: sample-apps.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/docs/samples/sample-apps.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- sample-apps.xml 24 May 2002 14:55:38 -0000 1.5
+++ sample-apps.xml 24 Jun 2002 10:44:32 -0000 1.6
@@ -11,12 +11,12 @@
</group>
<group name="Web Applications">
- <sample name="Protected Area" href="protected/login">
+ <sample name="Protected Area" href="samples/protected/login">
An example web-application built around db-authenticator,
form-validator, session-validator and session-invalidator
actions.
</sample>
- <sample name="Modular Database Actions" href="mod-db/user-list">
+ <sample name="Modular Database Actions" href="samples/mod-db/user-list">
An example web-application built around database actions from the
modular package that supports auto increments and more.
</sample>
1.1 xml-cocoon2/src/webapp/samples/mod-db/database.xml
Index: database.xml
===================================================================
<root>
<connection>personnel</connection>
<!-- this is only used when no connection is specified in sitemap -->
<!-- a table consists of key attributes and plain values, keys are
handled differently on operations. Most significantly when
inserting a new row, we need to determine if a value needs to
be set by the action or wheter it's an autoincrement. Next,
autoincrements work differently on different DBMSs, so we need
special support to find out about the value set by the DBMS.
-->
<table name="user" alias="user">
<!-- @name is the table's name in the DB -->
<!-- @alias is used instead (if present) for those weirdos that put -->
<!-- complex queries into @name ;-) You obviously loose all but select -->
<!-- functionality, although this is not enforced. -->
<keys>
<key name="uid" type="int" autoincrement="true">
<!-- @name is the column's name -->
<!-- @type is the column's jdbc type -->
<!-- @autoincrement : column value is determined by special component -->
<mode name="auto" type="autoincr"/>
<!-- this entry says:
when inserting a new column into a autoincrement column
(@type="autoincr"), use the module named "auto" to find out about
how to handle this column. All other operations use the default
mode.
There are two distinct mode types: "autoincr" for insert
operations on autoincrement columns and "others" for all other
(delete, update, select) operations on autoincrement columns and
all operations on other columns.
-->
</key>
</keys>
<values>
<value name="name" type="string"></value>
<value name="firstname" type="string"></value>
<value name="uname" type="string"></value>
</values>
</table>
<table name="user_groups">
<keys>
<key name="uid" type="int">
<!-- Next we have two different modes: "request" and
"attrib". See below for explanation. -->
<mode name="request" parameter="user_groups.uid" type="request"/>
<mode name="attribute"
parameter="org.apache.cocoon.components.modules.output.OutputModule:user.uid[0]"
type="attrib"/>
<!-- note here, that the actual parameter has a row index
to it. We don't expect to insert more than one user plus
her groups at any time, so we append just "[0]". However,
if that would be the case, we could let this column be
part of a set and ask for "[*]" instead. Might be tricky
to find the associated groups, though, if we insert x
users plus y_1, y_2, ... , y_x groups.... -->
</key>
<key name="gid" type="int" set="master">
<!-- now, this is tricky: when we need to insert multiple
rows, those attributes that differ in these rows are
marked to belong to a "set". One column is marked to be
the "master" while all others need to be "slaves". A
master is used to obtain a sorted set of index values for
these rows. These will then be used to get the actual
values for the master and slave columns. Note that it is
not necessary to have the master be a key column. Note too, that an
autoincrement column may not serve as a master here.
This attribute may be specified on a column level or on a
mode level to allow different behavious. Mode level @set
is only considered if @set is not present on column level.
Plus, as deletes and selects consider only key attributes while
updates consider values as well, there's no harm having a single
set for these three actions. In this case the set master needs to
be a key column, though.
-->
<!-- special mode type "all" is used for all operations -->
<mode name="request" parameter="user_groups.gid" type="all"/>
</key>
</keys>
</table>
<table name="groups">
<keys>
<key name="gid" type="int" autoincrement="true">
<mode name="auto" type="autoincr"/>
</key>
</keys>
<values>
<value name="gname" type="string"/>
</values>
</table>
<!-- the existing DB actions try to work on all tables listed in
this descriptor file. Just like some other newer actions this
one also allows for table-sets. If no set is found, it
defaults to the previous behaviour. Note though, that the
syntax is slightly different from the "old" DB actions file. -->
<table-set name="user">
<table name="user"/>
</table-set>
<table-set name="groups">
<table name="groups"/>
</table-set>
<table-set name="user+groups">
<table name="user"/>
<table name="user_groups" others-mode="attrib"/>
<!-- below we have another table set that inserts data into
user_groups. When inserting into user_groups alone, we'd know
the uid before hand, but when inserting a new user as well, we
need to find out the autoincrement value first. Therefore we
need a different approach to obtain that value. So we can
instruct the action to use a different type (here "attrib") which reads
the result from the first insert operation.
-->
</table-set>
<table-set name="user_groups">
<table name="user_groups" others-mode="request"/>
</table-set>
</root>
1.1 xml-cocoon2/src/webapp/samples/mod-db/edit-groups.xsp
Index: edit-groups.xsp
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:esql="http://apache.org/cocoon/SQL/v2"
xmlns:xsp-request="http://apache.org/xsp/request/2.0"
>
<!--
-->
<xsp:structure>
<xsp:include>java.util.Enumeration</xsp:include>
</xsp:structure>
<page>
<title>edit-groups</title>
<esql:connection>
<esql:pool>personnel</esql:pool>
<xsp:logic>
String user = <xsp-request:get-parameter name="user.uid"/>;
if ( user == null ) {
user = <xsp-request:get-parameter name="user_groups.uid"/>;
}
int uid=-1;
if ( user != null ) {
try {
uid = Integer.parseInt(user);
} catch ( NumberFormatException e ) {
uid = -1;
}
}
String uname="";
String name="";
String firstname="";
if ( uid != -1 ) {
<esql:execute-query>
<esql:query>select * from user where
uid=<esql:parameter><xsp:expr>uid</xsp:expr></esql:parameter></esql:query>
<esql:results>
<esql:row-results>
<xsp:logic>
uid=<esql:get-int column="uid"/>;
uname=<esql:get-string column="uname"/>;
name=<esql:get-string column="name"/>;
firstname=<esql:get-string column="firstname"/>;
</xsp:logic>
</esql:row-results>
</esql:results>
</esql:execute-query>
}
</xsp:logic>
<h1>Edit User's Groups</h1>
<table cellpadding="2" cellspacing="2" border="0">
<tbody>
<form>
<tr>
<td valign="Top" align="Right">uname
</td>
<td valign="Top">
<input type="text" name="user.uname">
<xsp:attribute
name="value"><xsp:expr>uname</xsp:expr></xsp:attribute>
</input>
</td>
<td>
</td>
</tr>
<tr>
<td valign="Top" align="Right">firstname, name</td>
<td>
<input type="text" name="user.firstname">
<xsp:attribute
name="value"><xsp:expr>firstname</xsp:expr></xsp:attribute>
</input>,
<input type="text" name="user.name">
<xsp:attribute name="value"><xsp:expr>name</xsp:expr></xsp:attribute>
</input>
</td>
<td>
<input type="hidden" name="user.uid">
<xsp:attribute name="value"><xsp:expr>uid</xsp:expr></xsp:attribute>
</input>
<input type="submit" name="upd-user" value="update"/>
</td>
</tr>
</form>
<tr>
<td valign="Top">
</td>
<td valign="Top" align="right">
<form>
<table border="1">
<tbody>
<tr>
<td>
<table border="0">
<tbody>
<tr>
<td>current groups</td>
</tr>
<tr>
<td>
<select multiple="1" name="user_groups.gid" size="7">
<esql:execute-query>
<esql:query>select gid, gname from user_groups,
groups where user_groups.gid = groups.gid and uid=<esql:parameter
type="int"><xsp:expr>uid</xsp:expr></esql:parameter> order by gname</esql:query>
<esql:results>
<esql:row-results>
<option>
<xsp:attribute name="value"><esql:get-string
column="gid"/></xsp:attribute>
<esql:get-string column="gname"/>
</option>
</esql:row-results>
</esql:results>
</esql:execute-query>
</select>
</td>
</tr>
<tr>
<td valign="Top">
<input type="hidden" name="user_groups.uid">
<xsp:attribute
name="value"><xsp:expr>uid</xsp:expr></xsp:attribute>
</input>
<input type="submit" name="remove-groups"
value="remove"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</td>
<td valign="Top" align="left">
<form>
<table border="1">
<tbody>
<tr>
<td>
<table border="0">
<tbody>
<tr>
<td>available groups</td>
</tr>
<tr>
<td>
<select name="user_groups.gid" multiple="1" size="7">
<esql:execute-query>
<esql:query>select gid, gname from groups where
gid not in (select gid from user_groups where uid=<esql:parameter
type="int"><xsp:expr>uid</xsp:expr></esql:parameter>) order by gname</esql:query>
<esql:results>
<esql:row-results>
<option>
<xsp:attribute name="value"><esql:get-string
column="gid"/></xsp:attribute>
<esql:get-string column="gname"/>
</option>
</esql:row-results>
</esql:results>
</esql:execute-query>
</select>
</td>
</tr>
<tr>
<td valign="Top">
<input type="hidden" name="user_groups.uid">
<xsp:attribute
name="value"><xsp:expr>uid</xsp:expr></xsp:attribute>
</input>
<input type="submit" name="add-groups"
value="add"/></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</td>
</tr>
</tbody>
</table>
<div align="Right"><form action="user-list"><input value="back to list"
type="submit"/></form></div>
</esql:connection>
<hr/>
<p><h3>Request Attributes</h3></p>
<p>
<table border="0">
<tbody>
<xsp:logic>{
Enumeration e=request.getAttributeNames();
while ( e.hasMoreElements() ) {
String attribute = (String) e.nextElement();
Object value = request.getAttribute(attribute);
<tr>
<td align="right"><xsp:expr>attribute</xsp:expr></td>
<td>="<xsp:expr>value</xsp:expr>"</td>
</tr>
}
}</xsp:logic>
</tbody>
</table>
</p>
<hr/>
<p><h3>Request Parameters</h3></p>
<p>
<table border="0">
<tbody>
<xsp:logic>{
Enumeration e=request.getParameterNames();
while ( e.hasMoreElements() ) {
String attribute = (String) e.nextElement();
Object[] value = request.getParameterValues(attribute);
for (int i=0; i < value.length; i++) {
<tr>
<td
align="right"><xsp:expr>attribute</xsp:expr>[<xsp:expr>i</xsp:expr>]</td>
<td>="<xsp:expr>value[i]</xsp:expr>"</td>
</tr>
}
}
}</xsp:logic>
</tbody>
</table>
</p>
<hr/>
</page>
</xsp:page>
1.1 xml-cocoon2/src/webapp/samples/mod-db/schema.sql
Index: schema.sql
===================================================================
-- this is the hsqldb schema file
-- to adapt it to another RDBMS, replace column type identity
-- with appropriate autoincrement type, e.g. SERIAL for informix
-- you might want to add "on delete cascade" to foreign keys in
-- tab�e user_groups
create table user (
uid integer identity primary key,
name varchar(50),
firstname varchar(50),
uname varchar(20),
unique (uname)
);
create table groups (
gid integer identity primary key,
gname varchar(20),
unique (gname)
);
create table user_groups (
uid integer,
gid integer,
primary key (uid,gid),
foreign key (uid) references user(uid),
foreign key (gid) references groups(gid)
);
1.1 xml-cocoon2/src/webapp/samples/mod-db/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<!-- ========================= Components ============================== -->
<map:components>
<!-- most components are inherited from parent sitemap -->
<!-- just make sure that defaults suit our needs -->
<map:generators default="file"/>
<map:transformers default="xslt"/>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:selectors default="browser"/>
<map:matchers default="wildcard">
<map:matcher logger="sitemap.matcher.modular.non-cached" name="uri"
src="org.apache.cocoon.matching.modular.WildcardMatcher">
<input-module name="URI"/>
</map:matcher>
<map:matcher logger="sitemap.matcher.modular.cached" name="cached-uri"
src="org.apache.cocoon.matching.modular.CachingWildcardMatcher">
<input-module name="URI"/>
</map:matcher>
</map:matchers>
<map:actions>
<!-- these action are in addition to the ones inherited -->
<!-- declare actions for database operations -->
<map:action name="mod-db-add"
src="org.apache.cocoon.acting.modular.DatabaseAddAction">
<descriptor>context://samples/mod-db/database.xml</descriptor>
<!-- shall we throw an exception in addition to rolling back
the transaction when encountering an error during
database ops?
-->
<throw-exception>false</throw-exception>
<!-- if results should be directed to another destination than the
default request attributes, use e.g.
<output>session</output>
this can also be specified on the fly through a map:parameter
named "output"
remember, that input-/output-modules need to be declared in your
cocoon.xconf in order to be used here.
-->
</map:action>
<map:action name="mod-db-del"
src="org.apache.cocoon.acting.modular.DatabaseDeleteAction">
<descriptor>context://samples/mod-db/database.xml</descriptor>
<throw-exception>false</throw-exception>
</map:action>
<map:action name="mod-db-upd"
src="org.apache.cocoon.acting.modular.DatabaseUpdateAction">
<descriptor>context://samples/mod-db/database.xml</descriptor>
<throw-exception>false</throw-exception>
</map:action>
<!-- a real world application would use the form validation here -->
<!-- this action just checks for existence of request parameters -->
<map:action name="req-params"
src="org.apache.cocoon.acting.RequestParameterExistsAction"/>
</map:actions>
</map:components>
<!-- ======================= Views ================================= -->
<map:views>
<map:view name="content" from-label="content">
<map:serialize type="xml" mime-type="text/plain"/>
</map:view>
</map:views>
<!-- ======================= Pipelines ================================= -->
<map:pipelines>
<map:pipeline>
<!-- ========================== Modular DB ================================= -->
<map:match pattern="">
<map:redirect-to uri="user-list"/>
</map:match>
<map:match pattern="*">
<!--
First, the logic to do all the database operations. Note,
that we do no parameter validation here, just see if some
parameters are present. For a real application, you'd
want to check their values as well. Note too, that in a
more complex setup you'd want to use an action set for
this rather than spell it out everywhere.
-->
<!-- ______________________________ inserts ______________________________
-->
<!-- add new groups to a user's groups -->
<map:act type="req-params">
<map:parameter name="parameters" value="add-groups user_groups.uid
user_groups.gid"/>
<map:act type="mod-db-add">
<map:parameter name="table-set" value="user_groups"/>
</map:act>
</map:act>
<!-- add onw new group -->
<map:act type="req-params">
<map:parameter name="parameters" value="add-group groups.gname"/>
<map:act type="mod-db-add">
<map:parameter name="table-set" value="groups"/>
</map:act>
</map:act>
<!-- add one new user -->
<!-- Actually, this one is not used anymore. The one below
works well when no groups are supplied.
-->
<map:act type="req-params">
<map:parameter name="parameters" value="add-user user.name user.firstname
user.uname"/>
<map:act type="mod-db-add">
<map:parameter name="table-set" value="user"/>
</map:act>
</map:act>
<!-- add one new user plus groups -->
<map:act type="req-params">
<map:parameter name="parameters" value="add-user-groups user.name
user.firstname user.uname"/>
<map:act type="mod-db-add">
<map:parameter name="table-set" value="user+groups"/>
</map:act>
</map:act>
<!-- ______________________________ updates ______________________________
-->
<!-- update one user -->
<map:act type="req-params">
<map:parameter name="parameters" value="upd-user user.uid user.name
user.firstname user.uname"/>
<map:act type="mod-db-upd">
<map:parameter name="table-set" value="user"/>
</map:act>
</map:act>
<!-- update one group -->
<map:act type="req-params">
<map:parameter name="parameters" value="upd-group groups.gid groups.gname"/>
<map:act type="mod-db-upd">
<map:parameter name="table-set" value="groups"/>
</map:act>
</map:act>
<!-- ______________________________ deletes ______________________________
-->
<!-- delete one user -->
<map:act type="req-params">
<map:parameter name="parameters" value="del-user user.uid"/>
<map:act type="mod-db-del">
<map:parameter name="table-set" value="user"/>
</map:act>
</map:act>
<!-- delete one group -->
<map:act type="req-params">
<map:parameter name="parameters" value="del-group groups.gid"/>
<map:act type="mod-db-del">
<map:parameter name="table-set" value="groups"/>
</map:act>
</map:act>
<!-- delete groups from a user's groups -->
<map:act type="req-params">
<map:parameter name="parameters" value="remove-groups user_groups.uid
user_groups.gid"/>
<map:act type="mod-db-del">
<map:parameter name="table-set" value="user_groups"/>
</map:act>
</map:act>
<!-- ______________________________ content
______________________________ -->
<map:generate type="serverpages" src="{1}.xsp"/>
<map:transform src="context://stylesheets/dynamic-page2html.xsl">
<map:parameter name="view-source" value="mod-db/{1}.xsp"/>
</map:transform>
<map:transform src="stupid.xsl"/>
<map:serialize/>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
1.1 xml-cocoon2/src/webapp/samples/mod-db/stupid.xsl
Index: stupid.xsl
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:variable name="tablecolor">#d0f0d0</xsl:variable>
<xsl:variable name="mediumtablecolor">#e0ffe0</xsl:variable>
<xsl:variable name="lighttablecolor">#f0fff0</xsl:variable>
<xsl:template match="sqltbl">
<xsl:element name="table">
<xsl:attribute name="border">1</xsl:attribute>
<xsl:attribute name="align">center</xsl:attribute>
<xsl:attribute name="bgcolor"><xsl:value-of
select="$tablecolor"/></xsl:attribute>
<xsl:element name="tr">
<xsl:apply-templates select="child::*[1]" mode="head"/>
</xsl:element>
<xsl:for-each select="child::*">
<xsl:element name="tr">
<xsl:apply-templates select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="sqltblrow" mode="head">
<xsl:for-each select="./child::*">
<xsl:element name="th">
<xsl:value-of select="name()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="sqltblrow">
<xsl:for-each select="./child::*">
<xsl:element name="td">
<xsl:attribute name="valign">top</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="sql-set">
<xsl:element name="table">
<xsl:attribute name="border">1</xsl:attribute>
<xsl:attribute name="bgcolor"><xsl:value-of
select="$mediumtablecolor"/></xsl:attribute>
<xsl:for-each select="./child::*">
<xsl:element name="tr">
<xsl:element name="td">
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template name="sql-set-item">
<xsl:value-of select="."/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="sql-list">
<xsl:element name="table">
<xsl:attribute name="border">1</xsl:attribute>
<xsl:attribute name="bgcolor"><xsl:value-of
select="$mediumtablecolor"/></xsl:attribute>
<xsl:variable name="i"><xsl:value-of select="position()"/></xsl:variable>
<xsl:for-each select="./child::*">
<xsl:element name="tr">
<xsl:element name="td">
<xsl:attribute name="bgcolor"><xsl:value-of
select="$lighttablecolor"/></xsl:attribute>
<xsl:value-of select="@pos"/>.
</xsl:element>
<xsl:element name="td">
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template name="sql-list-item">
<xsl:value-of select="."/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="sql-row">
<xsl:element name="table">
<xsl:attribute name="border">1</xsl:attribute>
<xsl:attribute name="bgcolor"><xsl:value-of
select="$mediumtablecolor"/></xsl:attribute>
<xsl:element name="tr">
<xsl:for-each select="./child::*">
<xsl:element name="td">
<xsl:apply-templates/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="sql-row-item">
<xsl:value-of select="."/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" priority="-1" mode="head">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="head"/>
</xsl:copy>
</xsl:template>
<xsl:template match="error">
<xsl:element name="table">
<xsl:attribute name="align">center</xsl:attribute>
<xsl:attribute name="width">100%</xsl:attribute>
<xsl:attribute name="bgcolor">#ffe0e0</xsl:attribute>
<xsl:element name="tr">
<xsl:element name="td">
<xsl:attribute name="align">center</xsl:attribute>
<xsl:element name="big">
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
1.1 xml-cocoon2/src/webapp/samples/mod-db/user-list.xsp
Index: user-list.xsp
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsp:page language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:esql="http://apache.org/cocoon/SQL/v2"
xmlns:xsp-request="http://apache.org/xsp/request/2.0"
>
<xsp:structure>
<xsp:include>java.util.Enumeration</xsp:include>
</xsp:structure>
<page>
<title>user-list</title>
<content>
<h1>Modular Database Actions</h1>
<hr/>
<p>The intention is to factor out those parts that are dependent on
the utilised DBMS as well as the methods used to obtain the values
and communicate results. Therefore three classes of modules
exist:</p>
<ol>
<li>Input Modules read data from some source (e.g. the request
object or session attributes or whatever)</li>
<li>Output Modules send the data to an arbitrary
destination. Again, this could be request attributes or
anything else. When the database transaction finishes, it is
signalled to them whether the transaction succeeded or
failed.</li>
<li>Database Modules determine the value of a key attribute
column in a database if it's is of auto increment type. This
could be by querying the database, reading from an arbitrary
source (e.g. request object) or just skipping the column when
inserting a row and querying the database afterwards. This
needs to be done e.g. for Informix's SERIAL or HSQLDB's
IDENTITY column types.</li>
</ol>
<hr/>
<h2>Current database content</h2>
<esql:connection>
<esql:pool>personnel</esql:pool>
<p>
<sqltbl>
<esql:execute-query>
<esql:query>select * from user order by name, firstname, uname,
uid</esql:query>
<esql:results>
<esql:row-results>
<sqltblrow>
<name>
<esql:get-string column="name"/>
</name>
<firstname>
<esql:get-string column="firstname"/>
</firstname>
<uname>
<esql:get-string column="uname"/>
</uname>
<action>
<form action="edit-groups">
<input type="hidden" name="user.uid">
<xsp:attribute name="value"><esql:get-string
column="uid"/></xsp:attribute>
</input>
<input type="submit" name="edit-user" value="edit"/>
</form>
<form>
<input type="hidden" name="user.uid">
<xsp:attribute name="value"><esql:get-string
column="uid"/></xsp:attribute>
</input>
<input type="submit" name="del-user" value="delete"/>
</form>
</action>
</sqltblrow>
</esql:row-results>
</esql:results>
<esql:error-results>
<error><esql:get-message/></error>
</esql:error-results>
</esql:execute-query>
<form method="Get">
<sqltblrow>
<name>
<input type="text" name="user.name" size="20" maxsize="20">
<xsp:attribute name="value"><!-- <xsp-request:get-parameter
default="" name="user.name"/> --></xsp:attribute>
</input>
</name>
<firstname>
<input type="text" name="user.firstname" size="20" maxsize="20">
<xsp:attribute name="value"><!-- <xsp-request:get-parameter
default="" name="user.firstname"/> --></xsp:attribute>
</input>
</firstname>
<uname>
<input type="text" name="user.uname" size="20" maxsize="20">
<xsp:attribute name="value"><!-- <xsp-request:get-parameter
default="" name="user.uname"/> --></xsp:attribute>
</input>
</uname>
<action>
<select multiple="1" name="user_groups.gid" size="4">
<esql:execute-query>
<esql:query>select gid, gname from groups order by
gname</esql:query>
<esql:results>
<esql:row-results>
<option>
<xsp:attribute name="value"><esql:get-string
column="gid"/></xsp:attribute>
<esql:get-string column="gname"/>
</option>
</esql:row-results>
</esql:results>
</esql:execute-query>
</select>
<input type="submit" name="add-user-groups" value="new user"/>
</action>
</sqltblrow>
</form>
</sqltbl>
</p>
<p>
<sqltbl>
<esql:execute-query>
<esql:query>select * from groups order by gname</esql:query>
<esql:results>
<esql:row-results>
<form>
<sqltblrow>
<gname>
<input type="text" name="groups.gname">
<xsp:attribute name="value"><esql:get-string
column="gname"/></xsp:attribute>
</input>
<input type="hidden" name="groups.gid">
<xsp:attribute name="value"><esql:get-string
column="gid"/></xsp:attribute>
</input>
<input type="submit" name="upd-group" value="update"/>
<input type="submit" name="del-group" value="delete"/>
</gname>
</sqltblrow>
</form>
</esql:row-results>
</esql:results>
<esql:error-results>
<error><esql:get-message/></error>
</esql:error-results>
</esql:execute-query>
<sqltblrow>
<gname>
<form>
<input type="text" name="groups.gname" size="20" maxsize="20">
<xsp:attribute name="value"><!-- <xsp-request:get-parameter
default="" name="groups.gname"/> --></xsp:attribute>
</input>
<input type="submit" name="add-group" value="new group"/>
</form>
</gname>
</sqltblrow>
</sqltbl>
</p>
<p>
<form>
<esql:execute-query>
<esql:query>select user.uid, user.uname, groups.gid, groups.gname from
user, user_groups, groups where user.uid=user_groups.uid and
user_groups.gid=groups.gid order by user.uname, groups.gname</esql:query>
<esql:results>
<sqltbl>
<esql:row-results>
<form action="edit-groups">
<sqltblrow>
<uname>
<input type="hidden" name="user.uid">
<xsp:attribute name="value"><esql:get-string
column="uid"/></xsp:attribute>
</input>
<esql:get-string column="uname"/>
</uname>
<gname><esql:get-string column="gname"/></gname>
<action>
<input value="edit groups" type="submit"/>
</action>
</sqltblrow>
</form>
</esql:row-results>
</sqltbl>
</esql:results>
<esql:error-results>
<error><esql:get-message/></error>
</esql:error-results>
</esql:execute-query>
</form>
</p>
</esql:connection>
<hr/>
<p><h2>Status Information</h2></p>
<p><h3>Request Attributes</h3></p>
<p>
<table border="0">
<tbody>
<xsp:logic>{
Enumeration e=request.getAttributeNames();
while ( e.hasMoreElements() ) {
String attribute = (String) e.nextElement();
Object value = request.getAttribute(attribute);
<tr>
<td align="right"><xsp:expr>attribute</xsp:expr></td>
<td>="<xsp:expr>value</xsp:expr>"</td>
</tr>
}
}</xsp:logic>
</tbody>
</table>
</p>
<p><h3>Request Parameters</h3></p>
<p>
<table border="0">
<tbody>
<xsp:logic>{
Enumeration e=request.getParameterNames();
while ( e.hasMoreElements() ) {
String attribute = (String) e.nextElement();
Object[] value = request.getParameterValues(attribute);
for (int i=0; i < value.length; i++) {
<tr>
<td
align="right"><xsp:expr>attribute</xsp:expr>[<xsp:expr>i</xsp:expr>]</td>
<td>="<xsp:expr>value[i]</xsp:expr>"</td>
</tr>
}
}
}</xsp:logic>
</tbody>
</table><br/>
</p>
<hr/>
</content>
</page>
</xsp:page>
1.1 xml-cocoon2/src/webapp/samples/protected/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<!-- ========================= Components ============================== -->
<map:components>
<map:generators default="file"/>
<map:transformers default="xslt"/>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:selectors default="browser"/>
<map:matchers default="wildcard"/>
<map:actions>
<map:action name="session-validator"
src="org.apache.cocoon.acting.SessionValidatorAction"/>
<map:action name="session-invalidator"
src="org.apache.cocoon.acting.SessionInvalidatorAction"/>
<map:action name="form-validator"
src="org.apache.cocoon.acting.FormValidatorAction"/>
<map:action name="db-authenticator"
src="org.apache.cocoon.acting.DatabaseAuthenticatorAction"/>
</map:actions>
</map:components>
<!-- ======================= Pipelines ================================= -->
<map:pipelines>
<map:pipeline>
<map:match pattern="">
<map:redirect-to uri="login"/>
</map:match>
<!-- ================= -->
<!-- Simple login page -->
<!-- ================= -->
<map:match pattern="login">
<map:generate src="docs/login.xml"/>
<map:transform src="stylesheets/simple-page2html.xsl"/>
<map:serialize/>
</map:match>
<!-- ========================================= -->
<!-- Form target which performs auth service -->
<!-- ========================================= -->
<map:match pattern="do-login">
<!-- first validate whether submitted values are ok -->
<map:act type="form-validator">
<map:parameter name="descriptor"
value="context://samples/protected/descriptors/params.xml"/>
<map:parameter name="validate" value="username"/>
<!-- now try to log in -->
<map:act type="db-authenticator">
<map:parameter name="descriptor"
value="context://samples/protected/descriptors/auth.xml"/>
<!-- now go to protected area -->
<map:redirect-to uri="protected"/>
</map:act>
</map:act>
<!-- something was wrong, try it again -->
<map:redirect-to uri="login"/>
</map:match>
<!-- ================ -->
<!-- Protected area -->
<!-- ================ -->
<map:match pattern="protected">
<!-- first validate whether user has logged in -->
<map:act type="session-validator">
<map:parameter name="descriptor"
value="context://samples/protected//descriptors/params.xml"/>
<map:parameter name="validate" value="username,department_id,theme"/>
<!-- generate protected content -->
<map:generate type="serverpages" src="docs/protected.xsp"/>
<map:transform src="stylesheets/{theme}-page2html.xsl"/>
<map:serialize/>
</map:act>
<!-- something was wrong, redirect to login page -->
<map:redirect-to uri="login"/>
</map:match>
<!-- ========================================= -->
<!-- Logout link which invalidates the session -->
<!-- ========================================= -->
<map:match pattern="do-logout">
<map:act type="session-invalidator">
<map:redirect-to uri="login"/>
</map:act>
</map:match>
<!-- Let parent sitemap treat it
<map:handle-errors>
<map:transform src="context://stylesheets/system/error2html.xsl"/>
<map:serialize status-code="500"/>
</map:handle-errors>
-->
</map:pipeline>
</map:pipelines>
</map:sitemap>
<!-- end of file -->
<!-- vim: set et ts=2 sw=2: -->
1.1 xml-cocoon2/src/webapp/samples/protected/descriptors/auth.xml
Index: auth.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is used for description of auth process
you specify here all columns that should be retrieved from specified
database table and to which request parameters they should be compared.
Values you specify can be automatically propagated to the created session
-->
<auth-descriptor>
<connection>personnel</connection>
<table name="employee">
<!--
because dbcol user has also matching request parameter, it will be used
for actual authentication, department_id will not be compared with
anything, it will just be along with username propagated to the session
-->
<select dbcol="name" request-param="username" to-session="username"/>
<select dbcol="department_id" to-session="department_id" type="long"/>
</table>
</auth-descriptor>
<!-- vim: set et ts=2 sw=2: -->
1.1 xml-cocoon2/src/webapp/samples/protected/descriptors/params.xml
Index: params.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is used for description of request and session parameters.
parameters that are nullable and are found being null are replaced with their
default values, non-nullable parameters can make the validation process fail.
-->
<parameters-descriptor>
<parameter name="username" type="string" nullable="no"/>
<parameter name="department_id" type="long" nullable="yes" default="0"/>
<parameter name="theme" type="string" nullable="yes" default="simple"/>
</parameters-descriptor>
<!-- vim: set et ts=2 sw=2: -->
1.1 xml-cocoon2/src/webapp/samples/protected/docs/login.xml
Index: login.xml
===================================================================
<?xml version="1.0"?>
<page>
<title>Login page</title>
<content>
<linkbar/>
<para>
This page serves as an example of simple web application built
around db-authenticator, form-validator, session-validator and
session-invalidator actions.
</para>
<para>Please log in using your name (Donald Ball will work)</para>
<form target="do-login">
<input type="text" name="username"/>
<input type="submit">Login</input>
</form>
</content>
</page>
<!-- vim: set et ts=2 sw=2: -->
1.1 xml-cocoon2/src/webapp/samples/protected/docs/protected.xsp
Index: protected.xsp
===================================================================
<?xml version="1.0"?>
<xsp:page language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:session="http://apache.org/xsp/session/2.0">
<page>
<title>Protected area</title>
<content>
<linkbar/>
<para>
Wow, you have entered secret area,
now its time to examine sub-sitemap and
think about what can be improved regarding flow control and especially
aspect capturing, so that it is not necessary to check session in every
map:match fragment. :-))
</para>
<para>Martin Man</para>
<para>You are logged in under username:
<session:get-attribute name="username"/></para>
<para>Your department id is:
<session:get-attribute name="department_id"/></para>
<para>Your web page theme is:
<session:get-attribute name="theme"/></para>
</content>
</page>
</xsp:page>
<!-- vim: set et ts=2 sw=2: -->
1.1
xml-cocoon2/src/webapp/samples/protected/stylesheets/error2html.xsl
Index: error2html.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:error="http://apache.org/cocoon/error/2.0">
<xsl:template match="error:notify">
<html>
<head>
<title>
<xsl:value-of select="@type"/>:<xsl:value-of select="error:title"/>
</title>
</head>
<body bgcolor="#ffffff">
<table border="0" bgcolor="#000000" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td bgcolor="#0086b2" colspan="2">
<font color="#ffffff" face="arial,helvetica,sanserif" size="+2">
<xsl:value-of select="error:title"/>
</font>
</td>
</tr>
<tr>
<td bgcolor="#0086b2" valign="top">
<font color="#ffffff" face="arial,helvetica,sanserif" size="+1">
<xsl:value-of select="@type"/>
</font>
</td>
<td bgcolor="#ffffff" >
<xsl:apply-templates select="error:message"/>
</td>
</tr>
<tr>
<td bgcolor="#0086b2" valign="top" colspan="2">
<font color="#ffffff" face="arial,helvetica,sanserif"
size="+1">details</font>
</td>
</tr>
<tr>
<td bgcolor="#0086b2" valign="top">
<font face="arial,helvetica,sanserif" color="#ffffff">from</font>
</td>
<td bgcolor="#ffffff">
<font face="arial,helvetica,sanserif">
<xsl:value-of select="@sender"/>
</font>
</td>
</tr>
<tr>
<td bgcolor="#0086b2" valign="top">
<font face="arial,helvetica,sanserif" color="#ffffff">source</font>
</td>
<td bgcolor="#ffffff">
<font face="arial,helvetica,sanserif">
<xsl:value-of select="error:source"/>
</font>
</td>
</tr>
<xsl:apply-templates select="error:description"/>
<tr>
<td bgcolor="#0086b2" valign="top" colspan="2">
<font color="#ffffff" face="arial,helvetica,sanserif"
size="+1">extra info</font>
</td>
</tr>
<xsl:apply-templates select="error:extra"/>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="error:description">
<tr>
<td bgcolor="#0086b2" valign="top">
<font color="#ffffff" face="arial,helvetica,sanserif">description</font>
</td>
<td bgcolor="#ffffff">
<font face="arial,helvetica,sanserif">
<xsl:value-of select="."/>
</font>
</td>
</tr>
</xsl:template>
<xsl:template match="error:message">
<font face="arial,helvetica,sanserif">
<xsl:value-of select="."/>
</font>
</xsl:template>
<xsl:template match="error:extra">
<tr>
<td bgcolor="#0086b2" valign="top">
<font color="#ffffff" face="arial,helvetica,sanserif">
<xsl:value-of select="@description"/>
</font>
</td>
<td bgcolor="#ffffff">
<pre>
<xsl:value-of select="."/>
</pre>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
<!-- vim: set et ts=2 sw=2: -->
1.1
xml-cocoon2/src/webapp/samples/protected/stylesheets/simple-page2html.xsl
Index: simple-page2html.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="page">
<html>
<head>
<title>
<xsl:value-of select="title"/>
</title>
<META content="0" http-equiv="expires"/>
<META content="nocache" http-equiv="pragma"/>
</head>
<body bgcolor="white" alink="red" link="blue" vlink="blue">
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="title">
<h2 style="color: navy; text-align: center">
<xsl:apply-templates/>
</h2>
</xsl:template>
<xsl:template match="para">
<p align="center">
<i><xsl:apply-templates/></i>
</p>
</xsl:template>
<xsl:template match="form">
<form method="POST" action="{@target}">
<xsl:apply-templates/>
</form>
</xsl:template>
<xsl:template match="input">
<center>
<xsl:value-of select="@title"/>
<input type="{@type}" name="{@name}" value="{.}"/>
</center><br/>
</xsl:template>
<xsl:template match="linkbar">
<center>
[
<a href="login"> login </a>
|
<a href="protected"> protected </a>
|
<a href="do-logout"> logout </a>
]
</center>
</xsl:template>
</xsl:stylesheet>
<!-- vim: set et ts=2 sw=2: -->
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]