| Beans |
|
|
Reserved Properties The following properties are reserved for JBeans:-
|
|
Interface The getInterface() method is the significant method that allows the code to determine the primary interface for a Bean. Because can be implemented differently it is not possible to always determine the primary interface for a Bean at run time. The AbstractBean class can however hazard a guess (as the first interface in the class below itself), but this is not reliable. Knowing the interface for a Bean allows code to find the Beans correct Session, Home and Validation from the Class Context at run-time. |
|
Primary Name Property The Bean class has a primary name, this defaults to class+pk. This default will be overridden by any column with the name <ClassName>Name, for example a Table called Book may have a column called bookName. These defaults can be overridden by specifying a simple Java expression: - <ClassName>.primaryName=<Java expression> For example:- Person.primaryName=firstName + " " + lastname; |
|
Indexable Property The indexable property creates some extra methods for many-one relationships public int get<ClassName>Count() public <ClassName> get<ClassName>(int index ) and if the table has a toPrimaryName() then public <ClassName> indexOf<ClassName>( String primaryName )
|
|
Modified Property The modified property is used to determine whether the bean has been modified. This is used by some of the Home classes to determine whether to persist the bean to its store. Once a bean has been persisted it's modified property is set to false. |
|
Accessor Properties set and get/is methods are added for every property. Each method is fully documented. For example a the method signatures for a property called age would be written as: - public int getAge(); public void setAge( int age ) throws ValidationException; Every setter method throws a ValidationException. Where are property is nullable on the database an Object value is used, where a property is non-nullable on the database a primitive value is used. Simply changing the nullable property on the database will change the type of the property. For example if a property if the age property was optional the method signature would be written as: - public Integer getAge(); public void setAge( Integer age ); This default type behavior can be overridden by the PropertiesReader. Set and is/get methods are added for primary keys. Where the property is another bean, with a zero-one or one-one relationship, it is the other Bean and not the primary key that is set on the Bean. For example if a Car class had an Engine property then the following methods would be written on the Car class: - public Engine getEngine(); public void setEngine( Engine engine); |
|
Transforming Properties It is possible to transform properties when they are set on the bean. The syntax for doing this is as follows: - <ClassName>.<propertyName>.transform=<expression> For example: - MyTable.myColumn=String.toUpperCase( String.trim( % ) ); This will create the following code in the setter property: - myColumn = String.toUppercase( String.trim( myColumn ) ); Another common requirement in web application is that an empty strings should be converted to nulls, this is true for alot of web application servers that treat a null as an empty string. To get this behaviour for a single property use the syntax: - <ClassName>.<propertyName>.emptyAsNull=true To get this behaviour for the whole of a table use the syntax: - <ClassName>.emptyAsNull=true To get this behaviour across the whole database, use the syntax: - emptyAsNull=true |
|
Relationship Properties Similar to Accessor Properties, Relationship Properties refer to relationships between Beans of a zero-many or zero-one relationship. Where a Bean has a relationship one bean will have a set/get method and the other bean will have add/remove properties. For example two classes Car and Wheel, the Wheel class would have following methods written: - public Car getCar(); public void setCar( Car car ) throws ValidationException; The Car class would have the following methods written: - public void addWheel( Wheel wheel ); public void removeWheel( Wheel wheel ); public Enumeration getWheels(); public void clearWheels(); The code generator handles the recursive referencing between the related beans, so that setting a car on a wheel is the same as adding a wheel to a car. |
|
Transient Members By default all the member variables that are beans, or vectors are transient by default. Primitive types are not transient by default. This is to allow beans to be serialized independently, either over the wire or down to disk independently. The Lazy Bean foreign keys are not transient. This mean s To make a member variable transient use the following syntax: - <ClassName>.<propertyName>.transient=true To make a member variable transient use the following syntax: - <ClassName>.<propertyName>Transient=false |
|
Default Values Defaults can also be specified in the properties file. This adds in-line Java code to the constructor. <ClassName>.<propertyName>.default=<Java Value> For example: - User.amount.default=1.45 |
|
Bound Properties Bound properties are properties that fire property change events. Events are only constructed and fired when somebody is listening. By default properties are not bound. To make a property unbound, use the following syntax: - <ClassName>.<propertyName>.bound=false For example: - Room.width.constrained=true |
|
Constrained Properties Constrained properties are properties that fire VetoableChangeEvents and reverse any changes by handling PropertyVetoExceptions. Events are only constructed and fired when somebody is listening. By default properties are not constrained. To make a property constrained, use the following syntax: - <ClassName>.<propertyName>.constrained=true For example: - Room.width.constrained=true |
|
Array Properties Array properties are properties that are arrays of primitive values, such as Arrays of Strings, Dates, int, long, boolean, or Enumerated Types The Bean interface is the same as that of a foreign key (i.e. addX(X x)/removeX(X x)/get()/clear()). Where get() can return an Array, Iterator or Enumeration. By default array properties are written down to a database as a TEXT field. By default properties are not arrays. arrays can be speficied by declaring [] after the variable name , for example: readColumn.ObjectArray.20=dateTimeType[] DATETIME NULL To make a property an array, use the following syntax: - <ClassName>.<propertyName>.array=true For example: - Room.dates.array=true By default properties are mapped to TEXT. This can be altered to be a VARCHAR type if you know it will not grow beyond the capacity. <ClassName>.<propertyName>.array.type=VARCHAR(255)
|
|
Validated Properties When any property is set, by default, a validation method is called on the validator, which could throw a ValidationException. Validators are automatically generated, and offer a powerful barrier to dirty data being set on the beans. For example if a car registration is set then a method called on the car validator the following line of code is generated: - carValidator.validateRegistration( this, registation, "registration" ); This validation can be switched off for individual beans by setting the isValidated() method. If the validation is not required by default for a bean , use the following syntax: - <ClassName>Validated=false If validation is never required for a property, it can be omitted, using the following syntax: - <ClassName>.<propertyName>.Validated=false Custom Validators can be added to the |
|
ClientProperties Client Properties are 'custom' properties set on the bean. They are basically key-value pairs and allow data to be flexibly added. Because they are not type safe they are not recommended for applications as a long term fixed solution. Given a code generator is at hand it is wiser to use this. Every bean has a few methods to set and get client properties. public Map getClientProperties() throws ValidationException; public Object getClientProperty( Object key ) throws ValidationException; public void putClientProperty( Object key, Object value, boolean firePropertyEvent ) throws ValidationException; |
|
Comparing Beans Every bean is by default Compable, but assumes no sort order. To make a bean comparable specifying the following will add a public int compareTo( Object object ) method with the following code. <Class>.compareTo=<code> The com.javelin.util.DefaultComparator has some static methods that can be used to help sorting. For example House.compareTo=return DefaultComparator.compare( this.getPrimaryName(), ((Bean)object)getPrimaryName() ); |
|
listRelations The listRelations method is responsible for populating a vector with the beans related to this bean. The method is used to determine which other beans should be saved, created or loaded. The list is a set therefore duplicate values are not added, and an attempt to add a duplicate value breaks the recursive descent. The listRelations bean has the following signature: - public void listRelations( Vector list, int type ) throws ValidationException; The set of relations is determined by the type. The type can be one of : Bean.ASSOCIATES The Lazy beans can also keep track of the removed associates and dependents. The lazy bean does this because it is (one possible bean) responsible for persistence. Bean.REMOVED_ASSOCIATES The beans are added to the list is in the same order that they would be updated, or removed, and the reverse order that they would be created. By default the associates and dependents are added. This can be switched off using the following syntax: [[<Table>.]<propertyName>.]list[Associates|Dependents|RemovedAssociates|RemovedDependents]=false
Address.home.listAssociates=false Address.listAssociates=false listAssociates=false
|
|
Exposing Lists It is sometimes necessary to expose the underlying relationship between 2 beans as a list. <class>.<property>.exposeRelationshipList=true For example if the Room has a DEPENDENTS or ASSOCIATES relationship with a House readColumn.Room.1=house INTEGER NOT NULL ASSOCIATES House Room.house.exposeRelationshipList=true Will create the following method on the House class public void listRooms() throws ValidationException This property can also be set at the class and project level. <class>.exposeRelationshipList=true exposeRelationshipList=true |
|
Sort Relationship List It is sometimes necessary to keep the relationship list sorted automatically, so that when any propert changes that affects the sort order list is resorted, when the database is saved. This keeps the cache in line with the database, without having to do back to the database to get the resorted data. Setting this property automatically exposes the relationship list. <class>.<property>.sortRelationshipList=true This property can also be set at the class and project level. <class>.sortRelationshipList=true sortRelationshipList=true
|
|
Adding Methods Methods can be added to interfaces or classes. This true for Beans, Homes, Sessions or Validators. Methods can be specified in the properties file. <ClassName>.method.<Index>=<Full Method Declaration> This example adds in-line Java code to the ProductBean class. Product.method.0=public void calculate( double value ) If the method is abstract then the class becomes abstract and an user-defined binding needs to be added to the plugin ContextProperties. The user-defined binding can simply extend the generated implementation and add the implementation of the abstract methods. This example creates a method on the Product class that is abstract on the ProductBean. Product.method.0=public void calculate( double value ) The ProductBean is now abstract so that a user defined binding must be added. In this case to the Jdbc (2-tier) Context.Product.jdbc.Bean=com.mycompany.myproject.MyProduct N.B. By not specifying the method property the code is implicitly added as part of the constructor. To make the custom code a static initializer then simply name the method as ProductBean.method.0=static To include a more complex method in-line from a relative file specify the following: - ProductBean.method.0=public void calculate( double value
) To include a more complex method in-line from an absolute file specify the following: - ProductBean.method.0=public void calculate( double value
)
|
|
Changing extends and implements It is possible to simply add interfaces to Beans when calling the $CREATE CREATOR method You can extend an interface or extend or implement on a class using the following syntax, to override the existing extension or implements <ClassName>.extends=<className>, <className> For example to change the extends and implments properties on the JdbcXXXX bean JdbcXXXX.extends=com.yyy.MyJdbcInterceptor To change the interface: - com.yyy.XXXX.extends=com.yyy.MyJdbcInterceptor,java.io.Serializable Using the following syntax to append an interface: - <ClassName>=$CREATE <CREATOR TYPE>, $SELF=$INTERFACE <Interface> For example, if we had 3 tables (Country, State, City) that were all Locations we could put a Location interface on them: - Country=$CREATE $CREATOR, $SELF=$INTERFACE $PACKAGE.Location |
|
Adding Members Member can be added to any interfaces or classes. <ClassName>.member.N=<Full In-line Member Declaration> For example: - ProductBean.member.0=public final static STRING NUMBER =
"123"; |
|
Object Methods A toString method is automatically written. A hashcode for the bean is automatically written. An equals for bean based on its class and primary key is automatically written. |
|
Example Bean Here is a (simple) example of an Address Bean, to give the big picture of what is generated: - /* package com.javelin.jcommerce; import java.util.*; /** public interface Address extends Bean, Cloneable /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** /** |