Raible's Wiki

Raible Designs
Wiki Home
Recent Changes


  - Korean
  - Chinese
  - Italian
  - Japanese

QuickStart Guide
  - Chinese
  - French
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish
  - Japanese

User Guide
  - Korean
  - Chinese

  - Chinese
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish

  - Korean

Latest Downloads

Other Applications

Struts Resume
Security Example
Struts Menu

Set your name in

Edit this page

Referenced by

JSPWiki v2.2.33


Hide Menu


DTO in AppFuse using XSnapshot

Part I: Integrating XSnapshot in AppFuse - A HowTo for integrating the XSnapshot framework in AppFuse

About this Tutorial

This tutorial will show you how to integrating the XSnapshot framework into Appfuse. By default, in Appfuse, the forms and generated by the XDoclet task @struts.form, and the data transfert used the jakarta commons beanutils.

With XSnapshot, the form is always generated by a set of xdoclet tasks which generate a snapshot and a helper class that convert data between model and form classes.

Table of Contents

  • [1] Download the latest version Xsnapshot
  • [2] Integrate the libraries in AppFuse
  • [3] Integrate new gen-xsnapforms ANT-Task in the build.xml
  • [4] Add Xsnapshot files in the WAR
  • [5] Declaring XSnapshot Beans in the Spring container

Download the latest version Xsnapshot[#1]

First of all we need to Download the XSnapshot framework. Howerer, the "official" framework can't be integrated in the Struts version of AppFuse for a simple raison :

generated Struts form contain not the doclet @struts.form name="..."

 * This is the "projectForm" snapshot auto-generated from the 
 * Project class.
 * Please see the documentation for the original Project
 * class for documentation of each individual attribute.
 @see org.appfuse.model.Project

public  class ProjectForm 
  extends org.apache.struts.action.ActionForm 
  implements Serializable {

In this form generated example, for AppFuse, it should have a doclet @struts.form name="personForm".

In this case, appfuse tasks would not be able to generate the struts-config.xml. So I have modifie the XSnapshot sources, in particular the net/sf/xsnapshot/ressources/snapshot.xdt to add the doclet.

NOTE: xsnapshot form generation does not write the struts validator doclet write in the model classes sources so you can not use Struts validator :-(. I am looking to modifie xsnapshot sources...

So download this version of xsnapshot(info)

Integrate the libraries in AppFuse[#2]

  • Extract the archive in le lib directory
  • Add the following part to the lib/lib.properties file:
      # xsnapshot - http://xsnapshot.sourceforge.net
  • Add the common configuration declaration.

So the commons part would be like that

      # Commons - http://jakarta.apache.org/commons

      # New for XSnapshot


  • You have to add the reference to the xsnaphost classpath. It need, of course the two jar and others like In order to do this, you have to edit your properties.xml file

  <path id="xsnapshot.classpath">
    <fileset dir="${xsnapshot.dir}" includes="*.jar"/>
    <fileset dir="${xdoclet.dir}">
      <include name="*.jar"/>
    <pathelement location="${j2ee.dir}/lib/j2ee.jar"/>
    <pathelement location="${ant.home}/lib/ant.jar"/>
    <pathelement location="${commons-collections.jar}"/>
    <pathelement location="${commons-logging.jar}"/>
    <pathelement location="${commons-lang.jar}"/>

  • Finally, add xsnapshot jar in classpath for compiling web classes (Actions and forms)

Add this line in your properties.xml file at the end of definition

  <pathelement location="${xsnapshot.jar}"/>

Integrate new XSnapshot ANT-Tasks in the build.xml [#3]

In order to use cobertura with your junit tests, you have to add the cobertura ANT-tasks to your build.xml

  • Open your build.xml and add the following target :
        <target name="gen-snapshotforms" description="Builds xsnapshots files, if necessary" depends="">
          <taskdef name="xsnapshotdoclet" classname="net.sf.xsnapshot.ant.XSnapshotDocletTask" classpathref="xsnapshot.classpath"/>
          <xsnapshotdoclet destdir="${build.dir}/web/gen" verbose="true"  mergedir="${xdoclet.merge.dir}" >
            <fileset dir="src/dao" includes="**/*.java"/>
              <packageSubstitution packages="model" substituteWith="webapp.form"/>

          <xsnapshotdoclet destdir="${build.dir}/web/gen" verbose="true"  mergedir="${xdoclet.merge.dir}" >
            <fileset dir="src/dao" includes="**/*.java"/>
            <packageSubstitution packages="model" substituteWith="webapp.form"/>

The first line defines the xsnapshot doclet task, using the classpath defined before. The xsnapshotdoclet task defines three subtasks, , ,
and to generate the snapshots, helpers and the configuration file respectively. because you will generally want the output from the former two to go to a different place than the latter, you will need to run xsnapshotdoclet twice.

Best practice is to have the and output classes to a generated-src directory somewhere under your build directory. The above example shows the two executions
of . Mergedir refers to the directory where xsnapshot will look for merge files.the element specifies the classes on which to run xsnapshot.

the element allows you to define an automatic package replacement that should take place when xsnapshot encounters non fully qualified classnames. Normally, xsnapshot qualifies them, with the package of the class in which they are found; the package substitution modifies that.

source XSnapshot quickstart guide

  • add the following part the the gen-forms target:
          <antcall target="gen-snapshotforms" />

Add XSnapshot files in the WAR [#4]

  • add the following part the the package-web target in the war task:
        <lib file="${xsnapshot.jar}"/>
        <lib file="${commons-configuration.jar}" />

        <webinf file="${build.dir}/web/gen/xsnapshot.properties" />

Declare XSnapshot Beans in the Spring container [#5]

  • We start by declaring XSnapshot transformers.

A transformer specify how to transform a value of a property in a model to the value the matching property should have in a snapshot, or the reverse transformation. We will see later a Date-to-Input transformer for transforming Date into String.

Add the following into src/service/org/appfuse/service/applicationContext-service.xml

        <!-- SPECIAL DAO for transforming IDs to entities of arbitrary class -->
        <bean id="id-to-entity" parent="dao"

The id-to-entity transformer is used to retrieve a Object by is id using a dao

  • To convert model objects in forms (and inversement), xsnapshot need to create a registry which contains configuration.

Add the following part

        <!-- ======================== XSNAPSHOT SETUP ========================= -->
        <bean id="xsnapshotRegistry" class="net.sf.xsnapshot.spring.XSnapshotRegistryFactoryBean">
          <property name="configLocations">
          <property name="helperMappings">
          <property name="transformerMappings">
              <!-- invoked indirectly by xsnapshot -->
              <entry key="inverse-nested-property" value-ref="id-to-entity"/>

  • Declaring a XsnapshotUtils bean.

The XsnapshotUtils class contains methods for working with XSnapshot at runtime

        <bean id="xsnapshotUtils" class="net.sf.xsnapshot.XSnapshotUtils">
          <property name="registry" ref="xsnapshotRegistry"/>
  • run ant

Everything should run normaly....

like would say Matt
Total time: 1 minute 22 seconds

You are ready to use Xsnapshot in our Appfuse Project

Next Up: Part II: Implementing the example


Go to top   Edit this page   More info...   Attach file...
This page last changed on 06-Nov-2006 13:53:00 MST by DavidRouchy.