Release 0.5.2
Copyright © 2004 the_mindstorm. All rights reserved.
Revision History | |
---|---|
Revision 0.2 | 2004.10.25 |
updated on tag parameters (according to dtoGen™ 0.5.2) | |
Revision 0.1 | 2004.09.28 |
documentation according to version dtoGen™ 0.5 |
Abstract
dtoGen™ is a library which will help you obtain the data transfer objects out of the domain model objects without writting additional code.
List of Tables
List of Examples
Table of Contents
dtoGen™ is a java source generation tool that can ease the development of multi-tier systems by offering a reliable solution to obtain the data transfer objects out of the domain model objects without hand-writting additional code. Using a simple set of javadoc tags, dtoGen™ provides the possibility to define the whole set of data transfer objects used by your system.
Why another tool? There are already many code generation tools (XDoclet, SGen, XSnapshot, just to name a few) that provide the code generation functionality. The reason to create this new tool is that the actual available solutions do not allow to ensemble and/or extract from the domain model graph a very specific part (a good name of this could be snapshot. In the dtoGen™ notation I will call this: cutout). dtoGen™ offers a generic solution for this: it offers you the means to define your data transfer objects starting from the domain model in whatever format you need the information (by ensembling together more than one domain model classes, by extracting different info from different domain model classes, etc.).
dtoGen™ aims to provide you with a reliable solution for generating data transfer objects by fetching/ensembling only the needed information from your domain model classes [1]. Usually in a N-tier solution the domain model classes reside on the server side. The domain model classes are used for fetching/saving your info from/into a persistence storage (as a relational db, filesystem, etc). According to J2EE guiding rules, a good practice is to use data transfer objects [2] for transfering the domain model info through the layers, this requiring hand-writting of another graph of objects.
dtoGen™ tries to take this responsibility from the developer and let him concentrate on the real business.
I have imagined dtoGen™ to be used in the following scenarios: [3]
In this scenario you define the data transfer object starting from a single model object and grouping different info from other different model objects. You can include any number of bean properties from any number of model objects. The single limitation is that the main definition of the data transfer object resides in one domain object.
included in version 0.5
In this scenario you may define DTOs using inheritance. When using hierarchies of domain model objects, this will help you avoid code duplication inside the generated DTOs. You can define a hierarchy of DTO (using the parameter extends). The DTO hierachy can contain DTOs defined using dtoGen™ (which are to be generated) (using the parameter ext-mode set to internal) or an existing JavaBean (already defined) (using the parameter ext-mode set to external).
included in version 0.5
In this scenario you are allowed to split the definition of a DTO in multiple places (multiple model objects).
included in version 0.5
In this scenario you specify inside the domain model objects that the DTO to be used is an already defined JavaBean object. dtoGen™ will be responsible with the creation of the conversion tool (specified in the generate-util).
included in version 0.5
You can find out more about these scenarios by looking at the DTO definitions upon which dtoGen™ is tested. (test directory).
I use in this document the following definitions
[1] On this document I will use interchangeable domain model classses, domain classes and model classes, all refering to the domain model classes
[2] the abbreviation for data transfer object: DTO.
[3] I hope that the described scenarios cover a large range of possibilities. In case you imagine a new one please drop me an e-mail.
Table of Contents
dtoGen™ uses a simple system of javadoc tags to help it generate the DTO. It doesn't need anything else - neither at build time, nor at runtime. All you have to do is to include dtoGen™ javadoc tags in your sources and than let the provided ant task to do its work.
In the following section we will describe in more detail the tags used.
dtoGen™ uses 3 different javadoc tags on 2 java code elements:
defines the DTO[2] and some options for their generation
define the fields that are able to unique identify the entity [4]
We can imagine that any entity can provide a set of identity fields[4] because any domain model object is uniquely identifiable by some means.
Table 2.1. @dto.gen.class: class level tag
Parameter | Description | Default | Required (yes/no) |
---|---|---|---|
class | the name of the DTO. If fully qualified than dtoGen™ will extract the package. In case a simple name is used the DTO will be generated in the same package as the actual source. | ― | yes |
id | a unique identifier for DTO. It can be refered from element-type-id and key-type-id parameters. If no value is used than the class parameter value is considered the id. | ― | no |
def-mode | This parameter specifies the definition type of the DTO. Possible values: internal (specifies that the DTO is defined using dtoGen™ tags and that the DTO definition occurs only inside one and only one model object), synthetic (specifies that the DTO is defined using dtoGen™ tags and that the DTO definition is splitted in multiple model objects), external (specifies that the DTO is already defined outside the system) | internal | no |
extends | the fully qualified name of the parent class of the DTO. | ― | no |
ext-mode | Possible values: internal (default) and external. Specifies if the superclass is also defined with dtoGen™ (internal) or it is an already existing JavaBean (external). | internal | no |
implements | comma separated list of fully qualified names for implemented interfaces. By default dtoGen™ includes the java.io.Serializable | ― | no |
generate-tostring | flag indicating if a toString() should be generated. | false | no |
generate-equals | flag indicating if a equals(Object) should be generated. If set to true than a hashCode() method is also generated. Note:We recommend setting this to true. | false | no |
generate-util | flag indicating if an utility class with the name fqnTool should be generated. Possible values: true, false | true | no |
util-package | a package name to which the tool class to be generated. This is used only in case def-mode is set to external in order to avoid the generation of the util class in the same package as the external JavaBean. In case this parameter is not used than the package name of the external JavaBean is used for the util class. | ― | no |
include-code | name of a file to be included at the end of the generated DTO source. You must be aware of the fact that the included code is not parsed and so in order to have directly compilable sources you should use fully qualifies class names. In case the def-mode is set to synthetic than code from many files can be included. | ― | no |
The parameters used on bean property level share a common set of parameters described here.
Table 2.2. common parameters for bean property level
Parameter | Description | Default | Required (yes/no) |
---|---|---|---|
mode | the mapping mode. Possible values: simple, collection, array, map | simple | no |
name | the name of the bean property in the DTO | initial name | no |
type | fully qualified class name of the bean property in DTO or primitive type | initial type | no |
direct-convertor | a string in the format fqn#method or #method specifying the method responsible for the convertion from the original type to the type defined in type. In the 1st case it must be a static method, while in the second it must be a method available directly on the initial type object. | ― | only if type is used |
inverse-convertor | a string in the format fqn#method or #method specifying the method responsible for the convertion from type defined in type to the original type. In the 1st case it must be a static method, while in the second it must be a method available directly on the initial type object. | ― | only if type is used |
element-type | fully qualified class name of a collection or array element or map value element. | ― | yes (if mode is collection|array|map) |
element-type-id | in case the element-type is a POJO which represents the source for multiple DTOs, then specify the id of DTO to be used | ― | yes (only if element type is a POJO which represents the source of more than 1 DTO) |
element-convert-type | specifies the mapping for the element-type. This forces the convertion of original type to this type. | ― | no |
element-direct-convertor | equivalent of direct-convertor for element-type to element-convert-type. | ― | yes only if element-convert-type is used |
element-inverse-convertor | equivalent of inverse-convertor used to convert back element-convert-type to element-type. | ― | yes only if element-convert-type is used |
key-type | fully qualified class name of the keys used in map. Note: maps containing as keys different types are not supported. | ― | yes (for mode=map) |
key-type-id | equivalent of element-type-id for map keys | ― | yes (only if element type is a POJO which represents the source of more than 1 DTO) |
key-convert-type | equivalent of element-convert-type for map keys | ― | no |
key-direct-convertor | equivalent of element-direct-convertor for converting key-type to key-convert-type. | ― | yes only if key-convert-type |
key-inverse-convertor | equivalent for element-inverse-convertor for converting key-convert-type to key-type. | ― | yes only if key-convert-type |
use-in-tostring | specifies if the bean property should be used when genereting the
toString method. Possible values: true,
false
This parameter has no effect if the class level parameter generate-tostring is not set. | false | no |
The PK getter level tag does not require any additional parameters. You can use all common paramters.
Table 2.3. @dto.gen.pk: unique identifier getters level
Parameter | Description | Default | Required (yes/no) |
---|---|---|---|
commons parameters |
Table 2.4. @dto.gen.property: bean property getters level
Parameter | Description | Default | Required (yes/no) |
---|---|---|---|
commons parameters | |||
dtos | the DTOs to which this property must be perpetuated. Comma separated list of DTO ids | ― | yes |
use-in-equals | flag marking if this bean property should be used in equals implementation. Possible values: true, false | false | no |
The dto.gen.class tag and dto.gen.property use required parameters. If these are missing than the tag is dismissed and some error/warning message is printed.
For the generation of toString method inside a DTO I do the following checks: if there are any java bean properties having the class tag param use-in-tostring set to true than the generate-tostring must also be set to true. In case the generate-tostring is set to true and no java bean properties has the param use-in-tostring set to true than an empty toString method is generated.
The validations done for generating equals [5] method inside the DTO are the same as for toString generation.
Table of Contents
One of the most interesting things done automatically by dtoGen™ is the deep conversion of type. I will explain here the algorithms used for the type conversions.
Let's consider the following example domain model object:
Example 3.1. Domain model object
/** * @dto.gen.class class="FooDTO" */ public class Foo { private String name; private Bar bar; private FooBar country; // getters and setters /** * @dto.gen.property dtos="FooDTO" */ public String getName() { [...] } /** * @dto.gen.property dtos="FooDTO" */ public Bar getBar() { [...] } /** * @dto.gen.property dtos="FooDTO" */ public FooBar getFooBar() { [...] } }
Now, considering that the Bar domain model class defines also a mapping DTO, but the FooBar domain model class does not define a mapping DTO than the resulting FooDTO will be:
Using the name parameter the generated bean property name can be explicitely specified:
then the generated DTO will be:You can force a type conversion using type. Let's consider the following definition:
will result in the following DTO:Here is a short list with the dtoGen™ logging messages and warns/errors and their possible causes. An important thing to be known about dtoGen™ is that it is not restrictive. In case of a failure inside a definition it will be ignored, so if you think something is missing from the generated DTOs please check the messages.
marks the fact that I cannot decide what type should I use for generating the DTO property. This may happen as follows:
Table of Contents
This chapter is a simple list of known issues/todos to be solved asap. Each will give also the solution and the schedule.
Revision History | ||
---|---|---|
Revision 0.5 | 2004.09.25 | |
not yet supported |
Revision History | ||
---|---|---|
Revision 0.5 | 2004.09.25 | |
not yet supported |
Revision History | ||
---|---|---|
Revision 0.3 | 2004.09.15 |
Revision History | ||
---|---|---|
Revision 0.3 | 2004.09.15 |
I must thank the following for their contribution:
Many thanks guys. Much appreciation is coming your way directly from me :-).