Update of /cvsroot/xdoclet/xdoclet/xdocs
In directory sc8-pr-cvs1:/tmp/cvs-serv3724/xdocs
Modified Files:
valueobjects.xml
Log Message:
Fixed indentation and a huge amount of typos. Great work BTW!!
Index: valueobjects.xml
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet/xdocs/valueobjects.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** valueobjects.xml 17 Dec 2002 16:33:45 -0000 1.2
--- valueobjects.xml 17 Dec 2002 18:17:21 -0000 1.3
***************
*** 1,72 ****
<?xml version="1.0"?>
<document>
! <properties>
! <author email="[EMAIL PROTECTED]">Marcus Brito</author>
! <title>Using Value Objects</title>
! </properties>
! <body>
! <section name="Motivation">
! <p>
! The <valueobject> task is the xdoclet embodiement of the Value
! Object pattern, as described in <em>Core J2EE Patterns</em>.
! This pattern is also published in many other books and community sites
! around the world, and has proven to be an essential pattern to solve
! some EJB shortcomings.
! </p>
! <p>
! Every remote enterprise bean call may go through the network,
! implying a heavy performance penalty. For entity beans this is specially
! dangerous: every entity bean has a getter and a setter for its
! properties, and each of these calls would incur a remote, networked
! call. If your application is filling a form using the bean properties it
! would make a remote call for each property. No, no good.
! </p>
! <p>
! The solution is to create a coarse-grained object that contains some
! or all the bean properties and provide a method to create this object
! from the bean properties and another method to set the bean properties
! from such an object. This object is what we call the Value Object, a
! POJO (plain old java object) containing the enterprise bean property
! values. The following diagram illustrates this approach.
! </p>
! <p>
! {{{@todo: INSERT UML DIAGRAM HERE}}}
! </p>
! <subsection name="Multiple Value Objects Strategy">
! <p>
! Suppose you have defined a <code>Customer</code> entity with properties
! such as id, name, birth date, full address, number of children,
prefered
! TV series, wheather s/he likes fruit loops or cheerios and oodles of
! other information. You need them in different parts of your
application.
! However, sometimes you just need the customer ID and name. It would be
a
! waste of bandwidth and CPU to create a value object with all properties
! and pass it to your application, specially if you got thousands or
! millions of them.
! </p>
! <p>
! In a scenario like the one above, it would be useful to define
! multiple value objects, each one containing a different set of
! properties. You could have a <code>CustomerFull</code> VO containing
all
! properties and a <code>CustomerLight</code> VO containing just the
! customer ID and name.
! </p>
! <p>
! Your entity bean would provide methods to obtain both value objects,
! and perhaps methods to update the entity from both of them.The
following
! diagram illustrates this approach.
! </p>
! <p>{{{INSERT UML DIAGRAM HERE}}}</p>
! </subsection>
! </section>
! <section name="Using Value Objects in XDoclet">
! <p>
! XDoclet helps you to define and create your value objects. Below you
! can see a xdoclet-taged Entity Bean source code, with @tags related to
! Value Object generation. Let's take a look at a bean marked up to
! generate Value Objects. Please note that this is note a complete
! example: there are many tags missing, only the ones related to Value
! Objects are presented here.
! </p>
! <source>
package example.ejb;
--- 1,72 ----
<?xml version="1.0"?>
<document>
! <properties>
! <author email="[EMAIL PROTECTED]">Marcus Brito</author>
! <title>Using Value Objects</title>
! </properties>
! <body>
! <section name="Motivation">
! <p>
! The <valueobject> task is the XDoclet embodiment of the Value
! Object pattern, as described in <em>Core J2EE Patterns</em>.
! This pattern is also published in many other books and community
sites
! around the world, and has proven to be an essential pattern to solve
! some EJB shortcomings.
! </p>
! <p>
! Every remote enterprise bean call may go through the network,
! implying a heavy performance penalty. For entity beans this is
specially
! dangerous: every entity bean has a getter and a setter for its
! properties, and each of these calls would incur a remote, networked
! call. If your application is filling a form using the bean
properties it
! would make a remote call for each property. No, no good.
! </p>
! <p>
! The solution is to create a coarse-grained object that contains some
! or all the bean properties and provide a method to create this object
! from the bean properties and another method to set the bean
properties
! from such an object. This object is what we call the Value Object, a
! POJO (plain old java object) containing the enterprise bean property
! values. The following diagram illustrates this approach.
! </p>
! <p>
! {{{@todo: INSERT UML DIAGRAM HERE}}}
! </p>
! <subsection name="Multiple Value Objects Strategy">
! <p>
! Suppose you have defined a <code>Customer</code> entity with
properties
! such as id, name, birth date, full address, number of children,
preferred
! TV series, whether s/he likes fruit loops or cheerios and oodles
of
! other information. You need them in different parts of your
application.
! However, sometimes you just need the customer ID and name. It
would be a
! waste of bandwidth and CPU to create a value object with all
properties
! and pass it to your application, specially if you got thousands
or
! millions of them.
! </p>
! <p>
! In a scenario like the one above, it would be useful to define
! multiple value objects, each one containing a different set of
! properties. You could have a <code>CustomerFull</code> VO
containing all
! properties and a <code>CustomerLight</code> VO containing just
the
! customer ID and name.
! </p>
! <p>
! Your entity bean would provide methods to obtain both value
objects,
! and perhaps methods to update the entity from both of them. The
following
! diagram illustrates this approach.
! </p>
! <p>{{{INSERT UML DIAGRAM HERE}}}</p>
! </subsection>
! </section>
! <section name="Using Value Objects in XDoclet">
! <p>
! XDoclet helps you to define and create your value objects. Below you
! can see a XDoclet-tagged Entity Bean source code, with @tags related
to
! Value Object generation. Let's take a look at a bean marked up to
! generate Value Objects. Please note that this is note a complete
! example: there are many tags missing, only the ones related to Value
! Objects are presented here.
! </p>
! <source>
package example.ejb;
***************
*** 94,405 ****
public abstract class CustomerEJB implements EntityBean {
! /**
! * @ejb.value-object match="light"
! * @ejb.persistent-field
! */
! public abstract String getId();
! public abstract void setId(String id);
!
! /**
! * @ejb.value-object match="light"
! * @ejb.persistent-field
! */
! public abstract String getName();
! public abstract void setName(String name);
!
! /**
! * @ejb.value-object
! * aggregate="example.vo.ProductValue"
! * aggregate-name="PreferedProducts"
! * members="example.interfaces.Product"
! * members-name="PreferedProduct"
! * relation="external"
! * type="Collection"
! * @ejb.relation
! * name="Customer-Product"
! * role-name="customer-prefers-products"
! */
! public abstract Collection getPreferedProduts();
! public abstract void setPreferedProducs(Collection products);
!
! /**
! * @ejb.value-object
! * compose="example.vo.AddressValue"
! * compose-name="Addresses"
! * members="example.interfaces.Address"
! * members-name="Address"
! * relation="external"
! * type=Collection"
! * @ejb.relation
! * name="Customer-Address"
! * role-name="customer-has-addresses"
! */
! public abstract Collection getAddresses();
! public abstract void setAddresses();
!
! /**
! * @ejb.pesistent-field
! */
! public abstract int getNumberOfChildren();
! public abstract void setNumberOfChildren(int nof);
!
! /**
! * @ejb.persistent-field
! */
! public abstract boolean getLikesFruitLoops();
! public abstract void setLikesFruitLoops(boolean loops);
!
! /**
! * @ejb.persistent-field
! */
! public abstract boolean getLikesCheerios();
! public abstract void setLikesCheerios(boolean cheerios);
!
! /**
! * @ejb.interface-method
! */
! public abstract CustomerValue getCustomerValue();
!
! /**
! * @ejb.interface-method
! */
! public abstract CustomerLightValue getCustomerLightValue();
!
! /**
! * @ejb.interface-method
! */
! public abstract void setCustomerValue(CustomerValue value);
}
</source>
! <p>
! As you can see, there is only one tag you need to write to instruct
! xdoclet to generate value objects: <code>@ejb.value-object</code>.
! However, there ane many places and uses for this tag. Let's go through
! the basic steps to mark your bean until you get everything generated by
! xdoclet.
! </p>
! <subsection name="Value Object Declaration">
! <p>
! The first thing to do is to inform xdoclet which value objects it
! will generated for your bean. At class level, introduce the
! <code>@ejb.value-object</code> tag and supply at least the
! <code>name</code> and <code>match</code> parameter. The name
! parameter will tell xdoclet how to name the generated class for that
! value object. XDoclet will apply the pattern task parameter to the
! supplied name to determine the class name. The default pattern is
! <code>{0}Value</code>, so in this example we get two classes
! generated: <code>CustomerValue</code> and
<code>CustomerLightValue</code>.
! </p>
! <p>
! The <code>match</code> parameter will tell xdoclet which entity
! properties will be included in the generated value object. It's just
! an identifier that you will have to repeat at each property getter
! you want included in the value object. The <code>*</code> is a special
! value, meaning that all properties will be included. So, in this
! example the <code>CustomerValue</code> will have the same properties
! as the entity bean and the <code>CustomerLightValue</code> will have
! only the <code>id</code> and <code>name</code> properties.
! </p>
! </subsection>
! <subsection name="How Relationships Work">
! <p>Starting with a given source entity and the target
on the other side of a relation,
! there are 1:1, 1:n, n:1, and n:n relations. </p>
! <p>Internally to XDoclet, a relation is tracked
separately of either side of the
! relation using the name attribute of ejb:relation. If both sides of a
! relation have an @ejb:relation tag with a matching name attribute (the
"name"
! attribute is the key that is used to uniquely identify the relationship),
! information that would otherwise be incomplete can be inferred. But when the
! target relation does not have corresponding reverse visibility of the source
! in the relation and there is no @ejb:relation tag in the target with a
! matching name attribute, there are *some* cases where additional information
! needs to be provided to XDoclet in lieu of the missing information. The
! @ejb:target-relation tag provides the ability to provide this information.
! Thus, it is only needed or used when there is one-way visibility on a
! relation and the information that would normally be provided at the target is
! critical to the complete set of information that is necessary to generate the
! information about the relation as a whole.</p>
! <p>The primary case of where this is necessary is
where you have an 1:n
! unidirectional link (there is no link visibility on the n side of the link).
! Since 1:n links are modeled with the n side keeping a foreign key reference
! of the 1 side, attempting to generate a 1:n link without reverse visibility
! leaves XDoclet without the critical information it needs to know: the
! related-pk-field attribute. Using the target-relation tag allows this
! information to be provided. It's possible to model a 1:1 link this way,
! where the schema visibility is target-to-source, but the desired design
! visibility is source to target (for example, creating a new application on
! top of a legacy schema.) In this case the target-relation tag is used to
! describe the schema details, even though the generated APIs are reversed of
! that and under normal 1:1 circumstances, it would be fine to store the
! foreign key in the source entity.</p>
! <p>n:n and n:1 relations are the easy cases, because
the source entity contains
! the foreign key of the related entity. Whether or not there is reverse
! visibility is irrelevant to XDoclet since it has all the information it needs
! about the relation in the ejb:relation tag.</p>
! </subsection>
! <subsection name="Aggregation and Composition">
! <p>
! Value objects can have <code>composite</code> and
<code>aggregate</code>
! properties. These are multivalued properties that map an EJB
relationship.
! In this example we've got both aggregate and composite properties,
! those being <code>preferedProduts</code> and <code>addresses</code>,
! respectively.
! </p>
! <p>
! Aggregation should be used when the related object is not directly
! dependant on the one we're declaring the value object.
! <code>Product</code> has no direct dependency to <code>Customer</code>,
! so the <code>preferedProducts</code> relationship is just an
! aggregation. This means that the generated accessor methods for this
! relationship will lookup <code>Product</code> entities when adding
! them via the generated <code>addPreferredProduct()</code> method.
! </p>
! <p>
! Composition should be used when the related object is directly
! dependent on the one we're declaring the value object, and cannot
! exist without it. The creation of the related object is
! responsibility of the entity we're coding. <code>Address</code> is
! dependent on <code>Customer</code>, so the addresses relationhsip is
! a composition. This means that the generated accessor methods for
! this relationship will create and remove <code>Address</code>
! entities when adding and removing them via the generated
! <code>addAddress()</code> and <code>removeAddress()</code> methods.
! </p>
! <p>
! Aggregation and composition may be confusing at first. As a rule of
! thumb, considers object creation responsibility: if the entity we're
! coding isn't responsible for creating the related entity, then it's
! aggregation. If it is responsible for this, then it's composition. We
! ask you to take a look at the generated code so you can really grasp
the
! difference between the two.
! </p>
! <p>
! Now let's break down the many parameters that are needed to
! accomplish a multivalued property on a value object. The
! <code>type</code> parameter tells xdoclet what should be the type of
! the property in the value object. The possible values for this
! parameter are <code>Collection</code> and <code>Set</code>, in
! accordance with the EJB specification. In this example, both our
! multivalued properties uses <code>Collection</code> as type.
! </p>
! <p>
! The <code>aggregate-name</code> (or <code>composite-name</code>)
! parameter tells xdoclet how the accessor methods to this property in
! the value object should be called. The value of this paremeter should
be
! the method name, sans <code>get</code> or <code>set</code>. In this
! example, we will have methods called <code>getPreferedProducts()</code>
! and <code>setPreferedProducts()</code>, because PreferedProducts was
! the aggregate-name for the relationship.
! </p>
! <p>
! The <code>aggregate</code> (or <code>composite</code>) parameter
! tells xdoclet which should be the type of itens contained in
! the multivalued property. This should be a fully qualified class name.
! In this example, the <code>getAddresses()</code> method of the value
! object will return a <code>Collection</code> of
! <code>example.vo.AddressValue</code> objects. Thing should be
! starting to make sense, no?
! </p>
! <p>
! The <code>members</code> parameter tells xdoclet the fully qualified
! type of the related objects. This should be the type of the objects
! returned by the entity getter. Please note that <code>aggregate</code>
! and <code>aggregate-name</code> (or <code>composite</code> and
! <code>composite-name</code>) relate to names and types in the value
! object, while <code>members</code> and <code>members-name</code>
! relate to names and types in the entity bean. In this example, the
! <code>getPreferedProducts()</code> method returns a
! <code>Collection</code> of <code>example.interfaces.Product</code>
! objects, so this should be the value of the <code>members</code>
! parameter.
! </p>
! <p>
! The <code>members-name</code> parameter should be the name of the
! method in the related object that xdoclet should use to get the
! object that will be put in the multivalued value object property,
! without <code>get</code> or <code>set</code>. In this example,
! xdoclet needs to call a <code>Product.getProductValue()</code> method
! to obtain the <code>ProductValue</code>that will be put in the value
! <code>preferedProducts</code> property. Are you still with me?
! </p>
! <p>
! Last, the <code>relation</code> parameter, which only accepts the
! <code>external</code> value tells xdoclet that this property can be
! updated outside of the scope of this value object, so the generated
! method should always retrieve the property value. For relations,
! this is a no brainer: always include the
<code>relation="external"</code>
! parameter.
! </p>
! </subsection>
! <subsection name="Exposing Generated Methods">
! <p>
! Please notice the last three methods in this example. The Bean
! implementation class generated by xdoclet will contains them, but by
! default they won't be included in the remote or local interface for the
! bean. If you need to change that, you should declare them as abstract
! in your beans an tag them as you wish. In this example, we want the
! methods exposed in the remote interface, so we tag them with
! @ejb.interface-method. We don't want the
! <code>setCustomerLightValue()</code> method exposed, so we don't
! declare them here -- it will be in the generated implementation,
! however.
! </p>
! </subsection>
! </section>
! <section name="Customizing the &lt;valueobject&gt; task">
! <p>
! The <code>&lt;valueobject&gt;</code> task can be customized to
! your liking, to change things like the name of the package where the
! generated classes go and the name of the generated value objects.
! </p>
! <p>
! You can change the target package using a nested
! <a href="ant/xdoclet/tagshandler/PackageTagsHandler.PackageSubstitution.html">
!
<code>&lt;packageSubstitution&gt;</code>
! </a>
! element. For example, suppose we want all our value objecs generated
! under the <code>example.valueobjects</code> package.
! </p>
! <source><![CDATA[<valueobject>
! <packageSubstitution packages="ejb" substituteWith="valueobjects"/>
</valueobject>]]></source>
! <p>
! This tells xdoclet to substitute all packages names ending in "ejb" with
! a package name ending in "valueobject". The
! <code>&lt;packageSubstitution&gt;</code> element is common to all
! xdoclet subtasks, so it's a good thing to understand how to use it.
! </p>
! <p>
! Now, if you don't like the default naming pattern for value objects, you
! can change it by setting the <code>pattern</code> attribute for the
! <code>&lt;valueobject&gt;</code> task. The value must contain
! <code>{0}</code> in the name, which xdoclet will substitute with the
! bean name. In the above example, if we want our value objects to be
! named <code>CustomerVO</code> and <code>CustomerLightVO</code>, in the
! <code>examples.valueobject</code> package, this would be the task
! declaration:
! </p>
! <source><![CDATA[<valueobject pattern="{0}VO">
! <packageSubstitution packages="ejb" substituteWith="valueobjects"/>
</valueobject>]]></source>
! <subsection name="Modifying the generated value object">
! <p>
! XDoclet provides merge points in the value object template that you
! can use to add custom code to the generated value objects. If you
! don't know about merge points, you should <a href="merge.html">read
! about them now</a>.
! </p>
! <p>
! The merge point is just before the closing brace of the generated
! class and is called <code>valueobject-custom.xdt</code>. Please note
! that the merge file can contain any java code and can use the
! xdoclet template language. You can use this merge point to add
! new methods or inner classes to the generated value object. If
! you're <em>really</em> unhappy with the generated value object, you
! can completely replace the template used by xdoclet to generate it.
! Please refer to further documentation to learn about the template
! language.
! </p>
! </subsection>
! </section>
! </body>
</document>
--- 94,413 ----
public abstract class CustomerEJB implements EntityBean {
! /**
! * @ejb.value-object match="light"
! * @ejb.persistent-field
! */
! public abstract String getId();
! public abstract void setId(String id);
!
! /**
! * @ejb.value-object match="light"
! * @ejb.persistent-field
! */
! public abstract String getName();
! public abstract void setName(String name);
!
! /**
! * @ejb.value-object
! * aggregate="example.vo.ProductValue"
! * aggregate-name="PreferredProducts"
! * members="example.interfaces.Product"
! * members-name="PreferredProduct"
! * relation="external"
! * type="Collection"
! * @ejb.relation
! * name="Customer-Product"
! * role-name="customer-prefers-products"
! */
! public abstract Collection getPreferredProduts();
! public abstract void setPreferredProducs(Collection products);
!
! /**
! * @ejb.value-object
! * compose="example.vo.AddressValue"
! * compose-name="Addresses"
! * members="example.interfaces.Address"
! * members-name="Address"
! * relation="external"
! * type=Collection"
! * @ejb.relation
! * name="Customer-Address"
! * role-name="customer-has-addresses"
! */
! public abstract Collection getAddresses();
! public abstract void setAddresses();
!
! /**
! * @ejb.pesistent-field
! */
! public abstract int getNumberOfChildren();
! public abstract void setNumberOfChildren(int nof);
!
! /**
! * @ejb.persistent-field
! */
! public abstract boolean getLikesFruitLoops();
! public abstract void setLikesFruitLoops(boolean loops);
!
! /**
! * @ejb.persistent-field
! */
! public abstract boolean getLikesCheerios();
! public abstract void setLikesCheerios(boolean cheerios);
!
! /**
! * @ejb.interface-method
! */
! public abstract CustomerValue getCustomerValue();
!
! /**
! * @ejb.interface-method
! */
! public abstract CustomerLightValue getCustomerLightValue();
!
! /**
! * @ejb.interface-method
! */
! public abstract void setCustomerValue(CustomerValue value);
}
</source>
! <p>
! As you can see, there is only one tag you need to write to instruct
! XDoclet to generate value objects: <code>@ejb.value-object</code>.
! However, there are many places and uses for this tag. Let's go
through
! the basic steps to mark your bean until you get everything generated
by
! XDoclet.
! </p>
! <subsection name="Value Object Declaration">
! <p>
! The first thing to do is to inform XDoclet which value objects it
! will generated for your bean. At class level, introduce the
! <code>@ejb.value-object</code> tag and supply at least the
! <code>name</code> and <code>match</code> parameter. The name
! parameter will tell XDoclet how to name the generated class for
that
! value object. XDoclet will apply the pattern task parameter to
the
! supplied name to determine the class name. The default pattern is
! <code>{0}Value</code>, so in this example we get two classes
! generated: <code>CustomerValue</code> and
<code>CustomerLightValue</code>.
! </p>
! <p>
! The <code>match</code> parameter will tell XDoclet which entity
! properties will be included in the generated value object. It's
just
! an identifier that you will have to repeat at each property
getter
! you want included in the value object. The <code>*</code> is a
special
! value, meaning that all properties will be included. So, in this
! example the <code>CustomerValue</code> will have the same
properties
! as the entity bean and the <code>CustomerLightValue</code> will
have
! only the <code>id</code> and <code>name</code> properties.
! </p>
! </subsection>
! <subsection name="How Relationships Work">
! <p>
! Starting with a given source entity and the target on the other
side of a relation,
! there are 1:1, 1:n, n:1, and n:n relations.
! </p>
! <p>
! Internally to XDoclet, a relation is tracked separately of
either side of the
! relation using the name attribute of ejb.relation. If both sides
of a
! relation have an @ejb.relation tag with a matching name
attribute (the "name"
! attribute is the key that is used to uniquely identify the
relationship),
! information that would otherwise be incomplete can be inferred.
But when the
! target relation does not have corresponding reverse visibility
of the source
! in the relation and there is no @ejb.relation tag in the target
with a
! matching name attribute, there are *some* cases where additional
information
! needs to be provided to XDoclet in lieu of the missing
information. The
! @ejb.target-relation tag provides the ability to provide this
information.
! Thus, it is only needed or used when there is one-way visibility
on a
! relation and the information that would normally be provided at
the target is
! critical to the complete set of information that is necessary to
generate the
! information about the relation as a whole.
! </p>
! <p>
! The primary case of where this is necessary is where you have an
1:n
! unidirectional link (there is no link visibility on the n side
of the link).
! Since 1:n links are modeled with the n side keeping a foreign
key reference
! of the 1 side, attempting to generate a 1:n link without reverse
visibility
! leaves XDoclet without the critical information it needs to
know: the
! related-pk-field attribute. Using the target-relation tag allows
this
! information to be provided. It's possible to model a 1:1 link
this way,
! where the schema visibility is target-to-source, but the desired
design
! visibility is source to target (for example, creating a new
application on
! top of a legacy schema.) In this case the target-relation tag is
used to
! describe the schema details, even though the generated APIs are
reversed of
! that and under normal 1:1 circumstances, it would be fine to
store the
! foreign key in the source entity.
! </p>
! <p>
! n:n and n:1 relations are the easy cases, because the source
entity contains
! the foreign key of the related entity. Whether or not there is
reverse
! visibility is irrelevant to XDoclet since it has all the
information it needs
! about the relation in the ejb.relation tag.
! </p>
! </subsection>
! <subsection name="Aggregation and Composition">
! <p>
! Value objects can have <code>composite</code> and
<code>aggregate</code>
! properties. These are multi valued properties that map an EJB
relationship.
! In this example we've got both aggregate and composite
properties,
! those being <code>preferredProduts</code> and
<code>addresses</code>,
! respectively.
! </p>
! <p>
! Aggregation should be used when the related object is not
directly
! dependant on the one we're declaring the value object.
! <code>Product</code> has no direct dependency to
<code>Customer</code>,
! so the <code>preferredProducts</code> relationship is just an
! aggregation. This means that the generated accessor methods for
this
! relationship will lookup <code>Product</code> entities when
adding
! them via the generated <code>addPreferredProduct()</code> method.
! </p>
! <p>
! Composition should be used when the related object is directly
! dependent on the one we're declaring the value object, and cannot
! exist without it. The creation of the related object is
! responsibility of the entity we're coding. <code>Address</code>
is
! dependent on <code>Customer</code>, so the addresses
relationhsip is
! a composition. This means that the generated accessor methods for
! this relationship will create and remove <code>Address</code>
! entities when adding and removing them via the generated
! <code>addAddress()</code> and <code>removeAddress()</code>
methods.
! </p>
! <p>
! Aggregation and composition may be confusing at first. As a rule
of
! thumb, considers object creation responsibility: if the entity
we're
! coding isn't responsible for creating the related entity, then
it's
! aggregation. If it is responsible for this, then it's
composition. We
! ask you to take a look at the generated code so you can really
grasp the
! difference between the two.
! </p>
! <p>
! Now let's break down the many parameters that are needed to
! accomplish a multi valued property on a value object. The
! <code>type</code> parameter tells XDoclet what should be the
type of
! the property in the value object. The possible values for this
! parameter are <code>Collection</code> and <code>Set</code>, in
! accordance with the EJB specification. In this example, both our
! multi valued properties uses <code>Collection</code> as type.
! </p>
! <p>
! The <code>aggregate-name</code> (or <code>composite-name</code>)
! parameter tells XDoclet how the accessor methods to this
property in
! the value object should be called. The value of this parameter
should be
! the method name, sans <code>get</code> or <code>set</code>. In
this
! example, we will have methods called
<code>getPreferredProducts()</code>
! and <code>setPreferredProducts()</code>, because
PreferredProducts was
! the aggregate-name for the relationship.
! </p>
! <p>
! The <code>aggregate</code> (or <code>composite</code>) parameter
! tells XDoclet which should be the type of items contained in
! the multi valued property. This should be a fully qualified
class name.
! In this example, the <code>getAddresses()</code> method of the
value
! object will return a <code>Collection</code> of
! <code>example.vo.AddressValue</code> objects. Thing should be
! starting to make sense, no?
! </p>
! <p>
! The <code>members</code> parameter tells XDoclet the fully
qualified
! type of the related objects. This should be the type of the
objects
! returned by the entity getter. Please note that
<code>aggregate</code>
! and <code>aggregate-name</code> (or <code>composite</code> and
! <code>composite-name</code>) relate to names and types in the
value
! object, while <code>members</code> and <code>members-name</code>
! relate to names and types in the entity bean. In this example,
the
! <code>getPreferredProducts()</code> method returns a
! <code>Collection</code> of
<code>example.interfaces.Product</code>
! objects, so this should be the value of the <code>members</code>
! parameter.
! </p>
! <p>
! The <code>members-name</code> parameter should be the name of the
! method in the related object that XDoclet should use to get the
! object that will be put in the multi valued value object
property,
! without <code>get</code> or <code>set</code>. In this example,
! XDoclet needs to call a <code>Product.getProductValue()</code>
method
! to obtain the <code>ProductValue</code>that will be put in the
value
! <code>preferredProducts</code> property. Are you still with me?
! </p>
! <p>
! Last, the <code>relation</code> parameter, which only accepts the
! <code>external</code> value tells XDoclet that this property can
be
! updated outside of the scope of this value object, so the
generated
! method should always retrieve the property value. For relations,
! this is a no brainer: always include the
<code>relation="external"</code>
! parameter.
! </p>
! </subsection>
! <subsection name="Exposing Generated Methods">
! <p>
! Please notice the last three methods in this example. The Bean
! implementation class generated by XDoclet will contains them,
but by
! default they won't be included in the remote or local interface
for the
! bean. If you need to change that, you should declare them as
abstract
! in your beans an tag them as you wish. In this example, we want
the
! methods exposed in the remote interface, so we tag them with
! @ejb.interface-method. We don't want the
! <code>setCustomerLightValue()</code> method exposed, so we don't
! declare them here -- it will be in the generated implementation,
! however.
! </p>
! </subsection>
! </section>
! <section name="Customizing the &lt;valueobject&gt; task">
! <p>
! The <code>&lt;valueobject&gt;</code> task can be customized
to
! your liking, to change things like the name of the package where the
! generated classes go and the name of the generated value objects.
! </p>
! <p>
! You can change the target package using a nested
! <a
href="ant/xdoclet/tagshandler/PackageTagsHandler.PackageSubstitution.html">
! <code>&lt;packageSubstitution&gt;</code>
! </a>
! element. For example, suppose we want all our value objects generated
! under the <code>example.valueobjects</code> package.
! </p>
! <source><![CDATA[<valueobject>
! <packageSubstitution packages="ejb" substituteWith="valueobjects"/>
</valueobject>]]></source>
! <p>
! This tells XDoclet to substitute all packages names ending in "ejb"
with
! a package name ending in "valueobject". The
! <code>&lt;packageSubstitution&gt;</code> element is common
to all
! XDoclet subtasks, so it's a good thing to understand how to use it.
! </p>
! <p>
! Now, if you don't like the default naming pattern for value objects,
you
! can change it by setting the <code>pattern</code> attribute for the
! <code>&lt;valueobject&gt;</code> task. The value must contain
! <code>{0}</code> in the name, which XDoclet will substitute with the
! bean name. In the above example, if we want our value objects to be
! named <code>CustomerVO</code> and <code>CustomerLightVO</code>, in
the
! <code>examples.valueobject</code> package, this would be the task
! declaration:
! </p>
! <source><![CDATA[<valueobject pattern="{0}VO">
! <packageSubstitution packages="ejb" substituteWith="valueobjects"/>
</valueobject>]]></source>
! <subsection name="Modifying the generated value object">
! <p>
! XDoclet provides merge points in the value object template that
you
! can use to add custom code to the generated value objects. If you
! don't know about merge points, you should <a
href="merge.html">read
! about them now</a>.
! </p>
! <p>
! The merge point is just before the closing brace of the generated
! class and is called <code>valueobject-custom.xdt</code>. Please
note
! that the merge file can contain any java code and can use the
! XDoclet template language. You can use this merge point to add
! new methods or inner classes to the generated value object. If
! you're <em>really</em> unhappy with the generated value object,
you
! can completely replace the template used by XDoclet to generate
it.
! Please refer to further documentation to learn about the template
! language.
! </p>
! </subsection>
! </section>
! </body>
</document>
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
Xdoclet-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/xdoclet-devel