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>
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.