You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2007/09/23 12:35:12 UTC
svn commit: r578564 - in
/lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase:
part1.xml part2.xml
Author: andreas
Date: Sun Sep 23 03:35:07 2007
New Revision: 578564
URL: http://svn.apache.org/viewvc?rev=578564&view=rev
Log:
Continuing usecase tutorial
Added:
lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part2.xml
Modified:
lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part1.xml
Modified: lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part1.xml
URL: http://svn.apache.org/viewvc/lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part1.xml?rev=578564&r1=578563&r2=578564&view=diff
==============================================================================
--- lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part1.xml (original)
+++ lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part1.xml Sun Sep 23 03:35:07 2007
@@ -198,170 +198,10 @@
...
}]]></source>
- </section>
- <section>
- <title>Declaring the Usecase</title>
<p>
- Now we're ready to start working on the actual usecase. First, we tell Lenya about
- the usecase. The usecase declaration is a patch file for <code>cocoon.xconf</code>.
- It is located at <code>$MODULE_HOME/config/cocoon-xconf/usecase-addKnownPerson.xconf</code>.
- It adds the <em>person.addKnownUsecase</em> usecase component instance if it doesn't
- exist yet (determined by the <code>unless</code> attribute):
+ Now we can go on with the <a href="site:usecaseTutorialPart2">actual usecase</a>.
</p>
- <source xml:space="preserve"><![CDATA[<xconf xpath="/cocoon/usecases"
- unless="/cocoon/usecases/component-instance[@name = 'person.addKnownPerson']">
-
- <component-instance name="person.addKnownPerson" logger="lenya.modules.person"
- class="org.apache.lenya.modules.person.usecases.AddKnownPerson">
- <view template="modules/person/usecases/addKnownPerson.jx"/>
- </component-instance>
-
-</xconf>
-]]></source>
- <p>
- This usecase declaration specifies the usecase handler class (in our case
- <code>AddKnownPerson</code>) and the JX template which acts as the view for
- the usecase (<code>addKnownPerson.jx</code>). For a complete list of the generic
- usecase configuration options, refer to the <a href="site:abstractusecase">AbstractUsecase</a>
- documentation.
- </p>
- </section>
-
- <section>
- <title>Implementing the Usecase Handler Class</title>
- <p>
- The usecase handler object receives user input and manipulates the business objects,
- in our case the <code>Person</code> objects, accordingly. It has the following
- responsibilities:
- </p>
- <ul>
- <li>Prepare data to be displayed on the view,</li>
- <li>Validate user input and generate appropriate error messages, and</li>
- <li>Manipulate the business objects.</li>
- </ul>
- <p>
- If you want to follow a strictly object-oriented approach, the usecase handler class
- itself shouldn't contain any knowledge about the business logic. It belongs to the
- controller part of the <acronym title="Model-View-Controller">MVC</acronym> pattern
- (the other parts of the controller are the usecase sitemap and the flowscript).
- </p>
- <p>
- The following code snippet shows the usecase handler class.
- At this point, we implement only the two most important methods:
- </p>
- <ul>
- <li>
- <code>initParameters()</code> initializes the usecase parameters which are
- used to communicate between the usecase handler and the view. In our case, it
- compiles a list of <code>Person</code> objects, one for each document with the resource type
- <em>person</em>.
- </li>
- <li>
- <code>doExecute()</code> gets the <em>uuid</em> parameter from the view and adds
- the corresponding <code>Person</code> object to the list of known people.
- </li>
- </ul>
- <source xml:space="preserve"><![CDATA[public class AddKnownPerson extends DocumentUsecase {
-
- protected void initParameters() {
- super.initParameters();
-
- Document doc = getSourceDocument();
- Document[] allDocs = doc.area().getDocuments();
-
- try {
- Set peopleDocs = new HashSet();
- for (int i = 0; i < allDocs.length; i++) {
- if (allDocs[i].getResourceType().getName().equals("person")) {
- Person person = new Person(allDocs[i]);
- peopleDocs.add(person);
- }
- }
- setParameter("people", peopleDocs);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- protected void doExecute() throws Exception {
- super.doExecute();
-
- String uuid = getParameterAsString("uuid");
- Document doc = getSourceDocument();
- Person person = new Person(doc);
-
- Document knownDoc = doc.area().getDocument(uuid, doc.getLanguage());
- Person knownPerson = new Person(knownDoc);
-
- person.addKnownPerson(knownPerson);
- }
-
-}]]></source>
- </section>
-
- <section>
- <title>Implementing the View</title>
- <p>
- We're using a JX template to implement the view. It allows us to generate XHTML
- code using properties of Java objects which are passed as parameters from the usecase
- handler object.
- </p>
- <p>
- The page contains a form, passing the <em>lenya.usecase</em> and <em>lenya.continuation</em>
- parameters as hidden input fields. We choose POST as the form method because we want
- to manipulate data on the server, avoiding that the user submits the form multiple times.
- We generate a drop-down list containing an option for each person,
- using the UUID as the <code>value</code> attribute of the <code>option</code> element.
- Remember that the <em>people</em> parameter was set in the <code>initParameters()</code>
- method of the usecase handler class.
- </p>
- <source xml:space="preserve"><![CDATA[<page:page xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"
- xmlns:page="http://apache.org/cocoon/lenya/cms-page/1.0"
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:i18n="http://apache.org/cocoon/i18n/2.1" >
-
- <page:title>
- <i18n:text>Add Known Person</i18n:text>
- </page:title>
- <page:body>
-
- <jx:import uri="fallback://lenya/modules/usecase/templates/messages.jx"/>
-
- <form method="POST">
- <input type="hidden" name="lenya.usecase" value="${usecase.getName()}"/>
- <input type="hidden" name="lenya.continuation" value="${continuation.id}"/>
-
- <p>
- <i18n:text>Select a person you know:</i18n:text>
- </p>
- <p>
- <select name="uuid">
- <jx:forEach var="person" items="${usecase.getParameter('people')}">
- <option value="${person.getDocument().getUUID()}">
- <jx:out value="${person.getName()}"/>
- </option>
- </jx:forEach>
- </select>
- </p>
-
- <p>
- <input i18n:attr="value" name="submit" type="submit" value="Submit"/>
- <i18n:text> </i18n:text>
- <input i18n:attr="value" name="cancel" type="submit" value="Cancel"/>
- </p>
-
- </form>
- </page:body>
-</page:page>]]></source>
- </section>
-
- <section>
- <title>Adding the Menu Item</title>
- </section>
-
- <section>
- <title>What's Next?</title>
</section>
</body>
Added: lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part2.xml
URL: http://svn.apache.org/viewvc/lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part2.xml?rev=578564&view=auto
==============================================================================
--- lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part2.xml (added)
+++ lenya/docu/src/documentation/content/xdocs/docs/2_0_x/tutorials/usecase/part2.xml Sun Sep 23 03:35:07 2007
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 1999-2006 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: metadata.xml 55543 2004-10-26 00:14:59Z gregor $ -->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN"
+ "http://forrest.apache.org/dtd/document-v20.dtd">
+<document>
+ <header>
+ <title>Implementing a Usecase, Part 2: The Usecase</title>
+ </header>
+ <body>
+
+ <section>
+ <title>Declaring the Usecase</title>
+ <p>
+ Now we're ready to start working on the actual usecase. First, we tell Lenya about
+ the usecase. The usecase declaration is a patch file for <code>cocoon.xconf</code>.
+ It is located at <code>$MODULE_HOME/config/cocoon-xconf/usecase-addKnownPerson.xconf</code>.
+ It adds the <em>person.addKnownUsecase</em> usecase component instance if it doesn't
+ exist yet (determined by the <code>unless</code> attribute):
+ </p>
+ <source xml:space="preserve"><![CDATA[<xconf xpath="/cocoon/usecases"
+ unless="/cocoon/usecases/component-instance[@name = 'person.addKnownPerson']">
+
+ <component-instance name="person.addKnownPerson" logger="lenya.modules.person"
+ class="org.apache.lenya.modules.person.usecases.AddKnownPerson">
+ <view template="modules/person/usecases/addKnownPerson.jx"/>
+ </component-instance>
+
+</xconf>
+]]></source>
+ <p>
+ This usecase declaration specifies the usecase handler class (in our case
+ <code>AddKnownPerson</code>) and the JX template which acts as the view for
+ the usecase (<code>addKnownPerson.jx</code>). For a complete list of the generic
+ usecase configuration options, refer to the <a href="site:abstractusecase">AbstractUsecase</a>
+ documentation.
+ </p>
+ </section>
+
+ <section>
+ <title>Implementing the Usecase Handler Class</title>
+ <p>
+ The usecase handler object receives user input and manipulates the business objects,
+ in our case the <code>Person</code> objects, accordingly. It has the following
+ responsibilities:
+ </p>
+ <ul>
+ <li>Prepare data to be displayed on the view,</li>
+ <li>Validate user input and generate appropriate error messages, and</li>
+ <li>Manipulate the business objects.</li>
+ </ul>
+ <p>
+ If you want to follow a strictly object-oriented approach, the usecase handler class
+ itself shouldn't contain any knowledge about the business logic. It belongs to the
+ controller part of the <acronym title="Model-View-Controller">MVC</acronym> pattern
+ (the other parts of the controller are the usecase sitemap and the flowscript).
+ </p>
+ <p>
+ The following code snippet shows the usecase handler class.
+ At this point, we implement only the two most important methods:
+ </p>
+ <ul>
+ <li>
+ <code>initParameters()</code> initializes the usecase parameters which are
+ used to communicate between the usecase handler and the view. In our case, it
+ compiles a list of <code>Person</code> objects, one for each document with the resource type
+ <em>person</em>.
+ </li>
+ <li>
+ <code>doExecute()</code> gets the <em>uuid</em> parameter from the view and adds
+ the corresponding <code>Person</code> object to the list of known people.
+ </li>
+ </ul>
+ <source xml:space="preserve"><![CDATA[public class AddKnownPerson extends DocumentUsecase {
+
+ protected void initParameters() {
+ super.initParameters();
+
+ Document doc = getSourceDocument();
+ Document[] allDocs = doc.area().getDocuments();
+
+ try {
+ Set peopleDocs = new HashSet();
+ for (int i = 0; i < allDocs.length; i++) {
+ if (allDocs[i].getResourceType().getName().equals("person")) {
+ Person person = new Person(allDocs[i]);
+ peopleDocs.add(person);
+ }
+ }
+ setParameter("people", peopleDocs);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void doExecute() throws Exception {
+ super.doExecute();
+
+ String uuid = getParameterAsString("uuid");
+ Document doc = getSourceDocument();
+ Person person = new Person(doc);
+
+ Document knownDoc = doc.area().getDocument(uuid, doc.getLanguage());
+ Person knownPerson = new Person(knownDoc);
+
+ person.addKnownPerson(knownPerson);
+ }
+
+}]]></source>
+ </section>
+
+ <section>
+ <title>Implementing the View</title>
+ <p>
+ We're using a JX template to implement the view. It allows us to generate XHTML
+ code using properties of Java objects which are passed as parameters from the usecase
+ handler object.
+ </p>
+ <p>
+ The page contains a form, passing the <em>lenya.usecase</em> and <em>lenya.continuation</em>
+ parameters as hidden input fields. We choose POST as the form method because we want
+ to manipulate data on the server, avoiding that the user submits the form multiple times.
+ We generate a drop-down list containing an option for each person,
+ using the UUID as the <code>value</code> attribute of the <code>option</code> element.
+ Remember that the <em>people</em> parameter was set in the <code>initParameters()</code>
+ method of the usecase handler class.
+ </p>
+ <source xml:space="preserve"><![CDATA[<page:page xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"
+ xmlns:page="http://apache.org/cocoon/lenya/cms-page/1.0"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:i18n="http://apache.org/cocoon/i18n/2.1" >
+
+ <page:title>
+ <i18n:text>Add Known Person</i18n:text>
+ </page:title>
+ <page:body>
+
+ <jx:import uri="fallback://lenya/modules/usecase/templates/messages.jx"/>
+
+ <form method="POST">
+ <input type="hidden" name="lenya.usecase" value="${usecase.getName()}"/>
+ <input type="hidden" name="lenya.continuation" value="${continuation.id}"/>
+
+ <p>
+ <i18n:text>Select a person you know:</i18n:text>
+ </p>
+ <p>
+ <select name="uuid">
+ <jx:forEach var="person" items="${usecase.getParameter('people')}">
+ <option value="${person.getDocument().getUUID()}">
+ <jx:out value="${person.getName()}"/>
+ </option>
+ </jx:forEach>
+ </select>
+ </p>
+
+ <p>
+ <input i18n:attr="value" name="submit" type="submit" value="Submit"/>
+ <i18n:text> </i18n:text>
+ <input i18n:attr="value" name="cancel" type="submit" value="Cancel"/>
+ </p>
+
+ </form>
+ </page:body>
+</page:page>]]></source>
+ </section>
+
+ <section>
+ <title>Adding the Menu Item</title>
+ <p>
+ To be able to trigger the usecase, we have to add the corresponding menu item
+ to the menu of the person module, which is located at
+ <code>$MODULE_HOME/config/menu.xsp</code>. We add a menu block which shall be
+ visible only in the authoring area, right below the block containing the
+ editor menu items. The value of the <code>uc:usecase</code> attribute of the
+ <code><![CDATA[<item/>]]></code> element is the name of the usecase as specified
+ in the usecase declaration.
+ </p>
+ <source xml:space="preserve"><![CDATA[<menu i18n:attr="name" name="Edit">
+ <xsp:logic>
+ try {
+ Object doc = <input:get-attribute module="page-envelope"
+ as="object" name="document"/>;
+ if (doc instanceof Document && ((Document) doc).exists()) {
+ String doctype = <input:get-attribute module="page-envelope"
+ as="string" name="document-type"/>;
+ if ("person".equals(doctype)) {
+ <block areas="authoring">
+ <item uc:usecase="bxe.edit" href="?">
+ <i18n:text>With BXE</i18n:text>
+ </item>
+ <item uc:usecase="editors.oneform" href="?">
+ <i18n:text>With one Form</i18n:text>
+ </item>
+ </block>
+ <block areas="authoring">
+ <item uc:usecase="person.addKnownPerson" href="?">
+ <i18n:text>Add Known Person</i18n:text>
+ </item>
+ </block>
+ }
+ }
+ }
+ catch (Exception e) {
+ throw new ProcessingException("Error during menu generation: ", e);
+ }
+ </xsp:logic>
+</menu>]]></source>
+ </section>
+
+ <section>
+ <title>Setting the Usecase Permissions</title>
+ <p>
+ Finally we have to specify who shall be able to execute the usecase.
+ To accomplish this, we have to add an entry to the usecase policies file of the
+ publication(s) which will use the person module. The file is located at
+ <code>$PUB_HOME/config/access-control/usecase-policies.xml</code>.
+ We allow everyone with the <em>admin</em> or <em>editor</em> role to
+ execute the usecase:
+ </p>
+ <source xml:space="preserve"><![CDATA[<usecase id="person.addKnownPerson">
+ <role id="admin" method="grant"/>
+ <role id="edit" method="grant"/>
+</usecase>]]></source>
+ <p>
+ Now you can deploy the changes by running the build process and restarting the
+ servlet engine. After that you should be able to connect people using the
+ "knows" relation.
+ </p>
+ </section>
+
+ <section>
+ <title>What's Next?</title>
+ <p>
+ There are some important steps which are missing from the example:
+ </p>
+ <ul>
+ <li>
+ In <code>initParameters()</code>, you should exclude the person itself and
+ all people which she or he already knows.
+ </li>
+ <li>
+ If you set the relation from person A to person B, it probably makes sense
+ to set the relation from B to A at the same time.
+ </li>
+ <li>
+ To avoid sending stack traces to the user, you should validate the <em>uuid</em>
+ parameter: Is it provided? Does it refer to an existing person document?
+ You can do this kind of validation in the <code>doCheckExecutionConditions()</code>
+ method - just call <code>addErrorMessage()</code> for each validation error.
+ </li>
+ </ul>
+ </section>
+
+ </body>
+</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org