[richfaces-svn-commits] JBoss Rich Faces SVN: r13703 - in trunk/docs/realworld_app_guide/en/src/main/docbook: modules and 1 other directory.
richfaces-svn-commits at lists.jboss.org
richfaces-svn-commits at lists.jboss.org
Mon Apr 20 11:41:58 EDT 2009
Author: atsebro
Date: 2009-04-20 11:41:57 -0400 (Mon, 20 Apr 2009)
New Revision: 13703
Modified:
trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml
Log:
RF-5768: Real World Demo Application Tutorial Update for 3.3.1 release
Modified: trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml 2009-04-20 15:41:34 UTC (rev 13702)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml 2009-04-20 15:41:57 UTC (rev 13703)
@@ -4,6 +4,7 @@
<!ENTITY intro SYSTEM "modules/intro.xml">
<!ENTITY application_overview SYSTEM "modules/application_overview.xml">
<!ENTITY getting_started SYSTEM "modules/getting_started.xml">
+ <!ENTITY hiw SYSTEM "modules/hiw.xml">
]>
@@ -32,9 +33,9 @@
</bookinfo>
<toc/>
&intro;
- &application_overview;
+ &application_overview;
&getting_started;
-
+ &hiw;
</book>
Modified: trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml 2009-04-20 15:41:34 UTC (rev 13702)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml 2009-04-20 15:41:57 UTC (rev 13703)
@@ -12,9 +12,9 @@
<section>
<title>Used components</title>
- <para>Below there is a list of components used in "Photo album".</para>
+ <para>Below there is a list of components used in <property>Photo Album Demo</property>.</para>
<table>
- <title>Components used in "Photo album"</title>
+ <title>Components used in "Photo Album Demo"</title>
<tgroup cols="2">
<thead>
<row>
@@ -90,4 +90,323 @@
</table>
</section>
+ <section>
+ <title>Albums representation</title>
+
+ <section>
+ <title>Building the <rich:tree> on the page</title>
+
+ <para>
+ The <emphasis role="bold"><property><rich:tree></property></emphasis> component is designed for hierarchical data presentation and is used to build a tree structure. The component also supports built-in drag and drop functionality.
+ </para>
+ <para>
+ The <emphasis role="bold"><property><rich:tree></property></emphasis> component in the <property>Photo Album Demo</property> application helps to represent and implement inherently the "Shelves—Albums—Photos" hierarchy.
+ Shelf is the highest possible level in the tree hierarchy.
+ Shelfs are used to group thematic albums and may contain as many albums as needed.
+ Photos are not represented in the tree because it can be a great number of them and it can make a tree clumsy.
+ Photos are rendered in the center of the screen (hereinafter referred to as a watching area).
+ </para>
+
+ <para>
+ Implicitly, the <emphasis role="bold"><property><rich:tree></property></emphasis> component takes one the main place in the <property>Photo Album Demo</property> and is tightly bounded with the application logic.
+ There are several ways to implement the <emphasis role="bold"><property><rich:tree></property></emphasis>.
+ In the current application the <emphasis role="bold"><property><rich:tree></property></emphasis> is designed using a model tag <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>.
+ </para>
+ <para>
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component accepts a collection of elements, which are allowed to include lists, arrays, maps, XML NodeList or NamedNodeMap, and iterates through it.
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component repeats a hierarchical tree structure on a <code>xhtml</code> or <code>jsp</code> page in a component tree and can be nested without any limitations.
+ The code snippet below schematically shows the idea of how a tree can be built on a page with the help of adaptors:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<rich:tree>
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+ ...
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+</rich:tree>]]></programlisting>
+
+ <para>
+ When using <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component there is no need to specify
+ the <emphasis><property>"value"</property></emphasis> and <emphasis><property>"var"</property></emphasis> attributes for the <emphasis role="bold"><property><rich:tree></property></emphasis>.
+ The values for nodes to render are passed directly into the corresponding adaptor and the component performs all the necessary iterative work
+ (vizit the <ulink url="http://livedemo.exadel.com/richfaces-demo/richfaces/treeNodesAdaptor.jsf?c=treeNodesAdaptor"><rich:treeNodesAdaptor> page</ulink> on the RichFacesLiveDemo for more details).
+ </para>
+
+ <para>
+ Implementation of the <emphasis role="bold"><property><rich:tree></property></emphasis> in the application is very close to the model shown above.
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component has <nodes> attribute.
+ The top <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> in the <emphasis role="bold"><property><rich:tree></property></emphasis> in the Phot Album Demo application is responsible for shelfs rendering.
+ Its <emphasis><property>"nodes"</property></emphasis> attribute refers to <emphasis><property>getShelfs()</property></emphasis> method of the <code>ShelfManager</code> class and gets the collection of shelfs associated with the current user including all shared shelfs in the system.
+ Take a look at this method:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public List<Shelf> getShelfs(){
+ if(shelfs == null){
+ shelfs = shelfAction.getShelfs(user);
+ }
+ return shelfs;
+} ]]></programlisting>
+
+ <para>
+ After the <emphasis><property>"nodes"</property></emphasis> attribute of the <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for shelves rendering, receives the collection of shelves,
+ the iteration process switches to the nested <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for albums.
+ The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> <emphasis><property>"nodes"</property></emphasis> attribute refers in its turn to the <code>albums</code> field of the <code>Shelf</code> class
+ and takes a collection of all albums associated with the current shelf.
+ The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> renders all albums that belong to the current iterating shelf and then switches back to the "shelf" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> to render and iterate the next shelf in the shelves collection received earlier.
+ Here is how it looks in the <code>webapp/includes/index/tree.xhtml</code> file:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<rich:tree id="tree" switchType="client" treeNodeVar="treeNode" showConnectingLines="false" dragIndicator="dragIndicator" ajaxSubmitSelection="false"
+ adviseNodeOpened="#{treeManager.adviseNodeSelected}"
+ adviseNodeSelected="#{treeManager.adviseNodeSelected}"
+ iconCollapsed="/img/shell/tree_icon_plus.png"
+ iconExpanded="/img/shell/tree_icon_minus.png">
+ <rich:treeNodesAdaptor nodes="#{shelfManager.getShelfs()}" var="shelf">
+ <rich:treeNode reRender="mainArea" selectedClass="tree-selected-node">
+ <f:facet name="icon">
+ <h:graphicImage style="border: none" value="/img/shell/tree_icon_shelf.png">
+ <a4j:support reRender="tree, mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <rich:dropSupport id="shelfDND" acceptedTypes="album" dropValue="#{shelf}" dropListener="#{dndManager.processDrop}" reRender="mainArea, tree" />
+ <ui:include src="/includes/contextMenu/CMForShelf.xhtml" >
+ <ui:param name="shelf" value="#{shelf}" />
+ </ui:include>
+ <a4j:outputPanel>
+ <h:outputText value="#{shelf.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{shelf.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="tree, mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ </rich:treeNode>
+
+ <rich:treeNodesAdaptor var="album" nodes="#{shelf.albums}">
+ <rich:treeNode reRender="mainArea" dragType="album" dragValue="#{album}" dropValue="#{album}" acceptedTypes="image, album"
+ selectedClass="tree-selected-node" icon="img/shell/tree_icon_album.png">
+ <f:facet name="iconLeaf">
+ <h:graphicImage style="border: none" value="img/shell/tree_icon_album.png">
+ <a4j:support reRender="tree, mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <ui:include src="/includes/contextMenu/CMForAlbum.xhtml" >
+ <ui:param name="album" value="#{album}" />
+ </ui:include>
+ <rich:dndParam name="label" type="drag" value="#{album.name}" />
+ <a4j:outputPanel>
+ <h:outputText value="#{album.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{album.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="tree, mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ <rich:dropSupport id="php" acceptedTypes="image" dropValue="#{album}" dropListener="#{dndManager.processDrop}" reRender="mainArea, tree" />
+ </rich:treeNode>
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+</rich:tree>]]></programlisting>
+
+ <para>
+ The illustration below shows how the Shelves—Albums heirarchy is rendered on the page.
+ </para>
+
+ <figure>
+ <title>Shelves and albums nodes rendered with the help of the <rich:treeNodesAdaptor></title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/tree.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+</section>
+
+ <section>
+ <title>Drag-and-drop inside the <rich:tree></title>
+ <para>
+ Drag and drop features supported in the Photo Album Demo application are not so complicated as it may seem from the first view.
+ In this application we can mark out two types of drag-and-drop: one type takes place only inside the tree (between tree nodes) and another one — between the watching area and the tree.
+ The difference is not considerable enough to describe two types separately, but also not at all insignificant to be omitted here.
+ </para>
+
+ <para>
+ Let's examine drag-and-drop inside tree. The tree related components (<emphasis role="bold"><property><rich:tree></property></emphasis> and <emphasis role="bold"><property><rich:treeNode></property></emphasis>)
+ have their own attributes that provide drag-and-drop functionality. These attributes can be divided into two groups: those which provide drag (dragValue, dragListener, dragIndicator, dragType attributes) and those which provide drop operations (dropValue, dropListener, acceptedTypes, typeMapping).
+ </para>
+
+ <note>
+ <title>
+ Note:
+ </title>
+ <para>
+ Due to "Shelves—Albums—Photos" paradigm we can say that photos could be moved between albums, albums could be moved between shelves.
+ To avoid a mishmash, it's not allowed to place photos directly in shelves as well as nesting shelves inside shelves or albums inside albums.
+ </para>
+ </note>
+
+ <para>
+ All albums or images (<property>drag-and-drop zones</property> in terms of RichFaces drag-and-drop), which are assumed to be dragged, must be marked somehow in the application code.
+ For albums that are represented as tree nodes we will use previously mentioned <property>drag group</property> attributes:
+ </para>
+ <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor var="album" nodes="#{shelf.albums}">
+ <rich:treeNode dragType="album"
+ dragValue="#{album}"
+ dropValue="#{album}"
+ acceptedTypes="image, album" />
+ …
+</rich:treeNodesAdaptor>
+]]></programlisting>
+
+ <para>
+ To provide drop functionality for the marked albums we should mark shelves as drop zones in the application code too.
+ For this purpose we add the <emphasis role="bold"><property>rich:dropSupport</property></emphasis> component to the "shelf" node:
+ </para>
+ <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor nodes="#{shelfManager.getShelfs()}" var="shelf">
+ <rich:treeNode
+ <rich:dropSupport id="shelfDND"
+ acceptedTypes="album"
+ dropValue="#{album}"
+ dropListener="#{dndManager.processDrop}"
+ reRender="mainArea">
+ </rich:dropSupport>
+ …
+ </rich:treeNode>
+</rich:treeNodeAdaptor>]]></programlisting>
+
+ <para>
+ The <emphasis><property>"acceptedType"</property></emphasis> attribute tells the "shelf" node what types of dragged zones (albums in this case) it can accept.
+ The value for the <emphasis><property>"acceptedType"</property></emphasis> attribute corresponds the album <emphasis><property>"dragType"</property></emphasis> attribute.
+ The method binding that will process drag-and-drop operation should be pointed via <emphasis><property>"dropListener"</property></emphasis> attribute of the <emphasis role="bold"><property>rich:tree</property></emphasis>.
+ This method is shown in th e listing below:
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+public void processDrop(DropEvent dropEvent) {
+ Dropzone dropzone = (Dropzone) dropEvent.getComponent();
+ Object dragValue = dropEvent.getDragValue();
+ Object dropValue = dropzone.getDropValue();
+ if(dragValue instanceof Image){
+ if(!((Album)dropValue).getOwner().getLogin().equals(user.getLogin())){
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_PHOTO_ERROR);
+ return;
+ }
+ handleImage((Image)dragValue, (Album)dropValue);
+ }else if(dragValue instanceof Album){
+ if(!((Shelf)dropValue).getOwner().getLogin().equals(user.getLogin())){
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_ALBUM_ERROR);
+ return;
+ }
+ handleAlbum((Album)dragValue, (Shelf)dropValue);
+ }
+}
+...]]></programlisting>
+ <para>
+ The illustration below shows how the described above drag-and-drop features are rendered in the Photo Album Demo.
+ </para>
+ <figure>
+ <title>Dragging the "Flora" album from "Sport" shelf into the "Nature" (left) and the tree after drag-and-drop (right).</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/dnd.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>Upload images</title>
+ <para>The implementation of <emphasis role="bold"><property><rich:fileUpload></property></emphasis> in the Phot Album Demo uses the embedded Flash module that adds extra functionality to the component.
+ Here are the additional features that the Flash module provides:
+ </para>
+ <itemizedlist>
+ <listitem><para>Multiple files choosing;</para></listitem>
+ <listitem><para>Specification of permitted file types in the "Open File" dialog window;</para></listitem>
+ <listitem><para>A number of additional entry object properties.</para></listitem>
+ </itemizedlist>
+
+ <para>
+ The photos uploading functionality is realized on the <code>/includes/fileUpload/fileUploader.xhtml page</code>. Let's have a look at this page to find out how the uploader is imlemented:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<rich:fileUpload style="margin : 0px 0px 20px 0px; width : 504px; height : 200px; background : #f1f1f1; border : 1px solid #A1A1A1"
+ id="fileUpload"
+ allowFlash="true"
+ immediateUpload="false"
+ acceptedTypes="jpg,jpeg"
+ maxFilesQuantity="100"
+ autoclear="true"
+ fileUploadListener="#{fileUploadManager.listener}" >
+ <a4j:support event="onuploadcomplete" reRender="filesPanel, tree" />
+ <a4j:support event="onfileuploadcomplete" />
+ </rich:fileUpload>]]></programlisting>
+
+ <para>
+ The "<emphasis><property>FileUploadListener</property></emphasis>" attribute is binded with <code>fileUploadManager.listener</code> method which makes the main job on the upload.
+ Below is the <code>fileUploadManager.listener</code> method:
+ </para>
+ <programlisting role="JAVA"><![CDATA[public void listener(UploadEvent event) throws Exception {
+ UploadItem item = event.getUploadItem();
+ Image image = constructImage(item);
+ try {
+ extractMetadata(item, image);
+ } catch (Exception e1) {
+ addError(item, image, Constants.FILE_PROCESSING_ERROR);
+ return;
+ }
+ image.setAlbum(model.getSelectedAlbum());
+ if(image.getAlbum() == null){
+ addError(item, image, Constants.NO_ALBUM_TO_DOWNLOAD_ERROR);
+ return;
+ }
+ try{
+ if(imageAction.isImageWithThisPathExist(image)){
+ image.setPath(generateNewPath(image.getPath()));
+ }
+ imageAction.addImage(image);
+ }catch(Exception e){
+ addError(item, image, Constants.IMAGE_SAVING_ERROR);
+ return;
+ }
+ if(!fileManager.addImage(image.getFullPath(), item.getFile().getPath())){
+ addError(item, image, Constants.FILE_SAVE_ERROR);
+ return;
+ }
+ fileWrapper.getFiles().add(image);
+ Events.instance().raiseEvent(Constants.IMAGE_ADDED_EVENT, image);
+ item.getFile().delete();
+}]]></programlisting>
+
+<para>
+ When a photo is added into the uploader, the first thing it does is saving this photo in the file system.
+ The uploaded files are stored in the temporary folder in the computer file system.
+ For this purpose the value of the <code>createTempFile</code> parameter in <code>Ajax4jsf Filter</code> section should be set to <code>true</code>.
+ Below in the <code>Web.xml</code> file Ajax filter section:
+</para>
+
+ <programlisting role="XML"><![CDATA[...
+<init-param>
+ <param-name>createTempFiles</param-name>
+ <param-value>true</param-value>
+</init-param>
+...]]></programlisting>
+
+ <para>
+ Then the uploader creates an <code>Image</code> object and extracts all image metadata such as Camera name, Image size etc.
+ Then it sets an album and generates a new path to it.
+ The system should save six different sizes of the photo.
+ After the photo was added into the data base the system removes a temporary file created for storage.
+ </para>
+
+
+ </section>
+
+
</chapter>
More information about the richfaces-svn-commits
mailing list