Chrysalis Model: JavaBeansThe Chrysalis model consists of ordinary JavaBean business objects. The JavaBean specification states that JavaBeans must:
JavaBean MetaDataChrysalis supports the use of any JavaBean, but the framework
functions more smoothly if the JavaBeans encode business object
metadata in the public class Item { private Long itemId; private String name; private int stock; public Long getItemId() { return this.itemId; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getStock() { return this.stock; } public void setStock(int stock) { this.stock = stock; } // Other methods: load(), save(), etc. } <!-- chrysalis.xml for JavaBean package --> <config> <class name="Item"> <property name="name" maxlength="20" /> <property name="stock" min="0" max="1000" /> </class> <!-- Other JavaBean configuration ... --> </config> Chrysalis use the Well Known AttributesThe Chrysalis framework defines a number of "well-known" attributes used elsewhere in the framework.
Some of these values ( Options ListAn options list specifies a list of legal values for a property,
and text descriptions of those values. The lists are used to
generate select lists in the user interface. Each list is
configured in the <property name="creditCardType"> <option key="1" text="Visa" /> <option key="2" text="Mastercard" /> <option key="3" text="American Express" /> <option key="4" text="Discover" /> </property> The <select name="creditCardType"> <option value="1">Visa</option> <option value="2">Mastercard</option> <option value="3">American Express</option> <option value="4">Discover</option> </select> You can customize how option lists are loaded by defining a
custom JavaBean Properties and Logical DatatypesLike controller method parameters, Chrysalis JavaBean properties are divided into simple and complex types:
You can define new datatypes for simple types. For example, you
could define a public class PhoneNumber { private final long phoneNumber; public PhoneNumber(long number) { this.phoneNumber = number; } public long getLongValue() { return this.phoneNumber; } public String toString() { int areaCode = (int) this.phoneNumber / 10000000; int prefix = (int) ((this.phoneNumber - areaCode * 10000000) / 10000); int suffix = (int) this.phoneNumber - areaCode * 10000000 - prefix * 10000; if (areaCode > 0) { return "(" + areaCode + ") " + prefix + "-" + suffix; } else { return prefix + "-" + suffix; } } } You can define a new converter for the new datatype. public class PhoneNumberConverter extends Converter { public Object parse(String value) throws ConversionException { try { StringBuffer buffer = new StringBuffer(); char[] chars = value.toCharArray(); for (int i=0; i<chars.length; i++) { if (Character.isDigit(chars[i])) { buffer.append(chars[i]); } } return new PhoneNumber(Long.parseLong(buffer.toString())); } catch (Exception ex) { throw new ConversionException(ex); } } public String format(Object value) { return String.valueOf(value); } } Chrysalis also allows "logical" datatype that are different from
the actual Java type of a field. For example, a
<!-- chrysalis.xml for JavaBean package --> <config> <class name="Item"> <property name="name" maxlength="20" /> <property name="stock" min="0" max="1000" /> <property name="price" datatype="Currency" /> </class> <!-- Other JavaBean configuration ... --> </config> The ValidationsThe primary use of JavaBean metadata is to generate validation logic. The same validations can be used in both the client (in JavaScript) and the server. Client-side validations are generated by the logic in the
<jutil:input object="item" property="stock" /> Server-side validations are handled by the
public class Item implements Serializable { private static Validator validator = Validator.findValidator(Item.class); private int stock; public void setStock(int stock) throws ValidationException { validator.validate(this, "stock", stock); this.stock = stock; } // Other logic ... } If the class in question is a legacy class that does not perform
its own validation logic, you can specify that Chrysalis will
invoke the validation logic external to the class (in the
BeanFilter), by setting the <!-- chrysalis.xml for JavaBean package --> <config> <class name="Item" external-validation="true"> <property name="name" maxlength="20" /> <property name="stock" min="0" max="1000" /> <property name="price" datatype="Currency" /> </class> <!-- Other JavaBean configuration ... --> </config> The Chrysalis JavaBean metadata will only handle simple, single-field validations. Complex or multi-field validations will require custom logic (Java in the JavaBeans, JavaScript in the UI). In Java, you can implement this custom validation logic by creating custom Validator subclasses, as documented in the javadoc for the Validator class. |