From Model to DTO

The DTO's are created based on the model classes and mappings, not the database. Any entity reference is replaced with a DTO-Identifer wrapper. This allows the DTO to use Entity's that have not been loaded and ensures that each DTOSession references exactly one instance for each entity. Much like the hibernate sessions.
	
public class PersonDTO extends blomo.dto.BLoMoDTO implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	
	private java.lang.Integer id;
	private java.lang.String firstName;
	private java.lang.String lastName;
	
	private blomo.dto.BLoMoDTOIdentifier origin;
	private blomo.dto.BLoMoDTOIdentifier father;
	private blomo.dto.BLoMoDTOIdentifier mother;
	
	private java.util.Map dateCountries = new java.util.Hashtable();
	
	private java.util.Set childrenAsMother = new java.util.HashSet();
	private java.util.Set childrenAsFather = new java.util.HashSet();
	
The methods are created by the same rules as in the model. So a collection or map has add,remove,clear and readOnly access and simple types or entity references have getter and setter methods.
Since DTO's are used to display and change content in spring webflow environments, the content is addressed via path names. To make sure the same method can be used in the java environment a series of methods are created for each DTO that accept a path name and resolve it.
The first method is getAttribute(path). It returns the value addressed by the path and also resolves deep links(when a path runs over multiple DTO's). This allows to configure the view inside a flow with the path origin.city and get the city name from the origin DTO. It also allows the programmer to use the same configuration inside the controller or service to retrieve the value. Since the DTO's are generated it is no problem to create the code and it frees the programmer of using reflection approaches to resolve a path.
	
	public Object getAttribute( java.lang.String fullpath ) {
		blomo.dto.DTOSession dtoSession = getDtoSession();
		java.lang.String firstStep;
		int i = fullpath.indexOf('.');
		if ( i == -1 ) {
			firstStep = fullpath;
			if ( "origin".equals(firstStep) )
				return getOrigin();
			...
		} else {
			firstStep = fullpath.substring(0,i);
			java.lang.String tail = fullpath.substring(i+1,fullpath.length());
			if ( "origin".equals(firstStep) ) {
				if ( getOrigin() == null ) {
					setOrigin(new blomo.dto.BLoMoDTOIdentifierImpl(dtos.OriginDTO.class,null,dtoSession.getNextDtoId()));
				}
				return getOrigin().getAttribute(tail);
			}
			...
		}
		return null;
	}
	
Other methods that accept a path are addToAttribute, removeFromAttribute, getDtoClassForAttribute. They allow to add or remove entrys from collection, maps, DTO's or simple types. The getDtoClass method is primarily used to verify if a path does exist. Regardless of the content it will only return null if the path is invalid otherwise it will return the type of the addressed content(in case of maps two types are returned).
To connect the DTO layer to the hibernate model two methods copyFrom and copyTo are used. copyFrom fills the DTO with the content of the entity and copyTo fills the entity with the content of the DTO. Any transient content in the DTOSession that is connected to a DTO that is copied to an entity will be resolved and copied as well. A special case of copieing content to the hibernate model is the copyOnlyRelationsTo method. It makes sure that if transient content is hidden behind a DTO that can be selected but not updated is retrieved as well without copieing not updateable content.