Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] - نسخه متنی

Larne Pekowsky

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







20.4. Writing to Databases


It would be possible to use the session transformer to populate an SQL insert statement with values from a form and then use the sql transformer to execute that statement. However, Cocoon provides a much more powerful and flexible technique based on the idea of

actions.

Actions are classes that are invoked prior to the beginning of a pipeline, and they are usually used to process form data. They serve a controller role in Cocoon very similar to that served by struts Actions, and it is no coincidence that they have the same name. However, Cocoon actions work very differently, and a number of classes are provided that are more general than classes written to work with struts.

Actions must be declared in sitemap.xmap, just like generators and transformers. The following entry loads a built-in class called DatabaseAddAction that can add a row to any table:


<map:actions>
<map:action
name="dbAdd"
src="org.apache.cocoon.acting.DatabaseAddAction"/>
</map:actions>

It is also necessary to declare one or more

action sets that will use these actions. An action set is simply a group of actions where the group as a whole has a name, as does each action within the group. For the purposes of this example the following definition will be sufficient:


<map:action-sets>
<map:action-set name="process">
<map:act type="dbAdd" action="CreateArtist"/>
</map:action-set>
</map:action-sets>

The group as a whole is called process, and the dbAdd action within this group is called CreateArtist. If this were a more complete application, there would likely also be entries called DeleteArtist and UpdateArtist within the process group. There would likely also be another action-set that would handle creation, deletion, and update of albums.

There also must be a pipeline entry that uses this action:


<map:match pattern="process-artis202">
<map:act set="process">
<map:parameter name="descriptor"
value="artist_table.xml"/>
<map:generate src="success.xml"/>
<map:serialize type="html"/>
</map:act>
<!-- If not invoked from page, show the form -->
<map:generate src="artist_form.xml"/>
<map:serialize type="html"/>
</map:match>

Chapter 10, although the syntax is significantly different. The definition for the artist table is shown in Listing 20.8.


Listing 20.8. The definition of the artist table


<?xml version="1.0"?>
<artist>
<connection>toolbook</connection>
<table name="artist">
<keys>
<key param="artist_id"
dbcol="artist_id"
type="int"
mode="manual"/>
</keys>
<values>
<value param="name" dbcol="name" type="string"/>
</values>
</table>
</artist>

Conceptually, this description is straightforward. The data source and table are both specified at the top. Within the table definition each value names a simple row and specifies its type. Each key represents a key in the table and specifies how it should be populated when new data is entered. A value of manual tells Cocoon to find the current maximum value of the column in the table, add one to that value, and use the result as the value for the new row. This is a form of

auto increment, which is similar to that provided by OJB, although it is important to note that the two methods are incompatible and hence OJB cannot be easily used with Cocoon.

The only remaining question is how Cocoon knows whether a form is invoking an action and, if so, which one. This is done by passing a specially named value through the form, which can be illustrated by artist_form.xml, shown in Listing 20.9.


Listing 20.9. The artist input form


&l202>
<head><title>Create artist</title></head>
<body>
<form action="process-artis202" method="GET">
<input type="text" name="name"/>
<input type="submit" name="cocoon-action-CreateArtist"
value="CreateArtist"/>
</form>
</body>
</html>

The text input of this form is perfectly standard. The submit name, cocoon-action-CreateArtist, is the key that tells Cocoon how to proceed. Cocoon knows from the entry in sitemap.xmap that the action set called process is being used. Cocoon will then look for any submitted value whose name starts with cocoon-action-. When one is found, the portion of the name following the second dash is taken to be the name of an entry in the specified set. In this case it will determine that the name is specifying an action called CreateArtist and will find that name in the definition of the process set, pointing at the action called dbAdd. This action will then be invoked with the name value from the form and the table descriptor. This is everything the action needs to construct an insert statement and update the database.

The success.xml file contains a message and a link back to artis202. The page itself doesn't need to do anything because everything has been handled by the action.

It is important to note that although this accurately describes the way in which Cocoon works, it is

not how Cocoon is typically used. Cocoon sites that use actions and perform database access are usually written in XSPExtensible Server Pagesa page language used by Cocoon that in many ways provides a complete replacement for JSPs, the standard tag library, and struts. XSP contains logic and iteration tags, a form validation mechanism, and more. Using XSP, there would be no need to know how Cocoon names its submit values because the creation of these form handlers

/ 207