The Alchemist works by identifying common patterns. These are not simply low-level programming patterns, but ones more akin to overall application structure. How is a system initialized? - or - How is data created?

The main patterns are described here, for more details check out the whitepaper describing the example Northwind implementation.

System Initialization

The standard GPO system includes a class OMClient that aids in system initialization. For each system, the Alchemist generates a specialized subclass of OMClient that provides access to the Root Object.

Root Object

After system initialization the Root Object provides the top level application interaction. For example, the Northwind system defines a Business class, of which an instance is the Root Object. This will provide creation and lookup methods to access other objects such as instances of Product.

Object Label

Each class may define a number of associated properties - a Contact may have a PostCode for example. In order to help with visualization, you may specify one of these properties to label the object.

Default Values

Any object property may be provided with a default value.

Required Properties

Some properties must be set. For example, a Contact requires a Name, it is not sufficient to simply declare a default value.

If a property is declared as required, then the class constructor will include the property value as a parameter.

Furthermore, generated creation methods will require the same parameters before themselves calling the constructor.

Type Restriction

This is a general solution to property validation.

Java provides simple types and classes, and at the language level this is sufficient: that a property is a Date a String or an Integer. But this is not sufficient when it comes to a system utilizing such values.

For example, a String value may be limited to some length, or to different ranges of characters - such as a Post Code.

An Integer may be limited to a range of values, or a Date may be used to indicate either a calendar day or to time some system event to millisecond precision.

An approach to dealing with this is the concept of type restriction.

Here is an example of a type restriction that could be used to validate a Post Code property:

regex:^[A-Z]{1,2}[0-9]{1,2}( [0-9][A-Z]{2})?$

...or this for a restriction on a Date property:

timeslot:am,pm

Such restrictions are declared to the Alchemist and are accessible to applications via a meta data interface in the generated code.

Object Associations

These are the essence of any object model. There are three standard types of associations: one-to-one, one-to-many and many-to-many.

How these associations are used though is decided by other patterns.

Association Roles

In our Northwind example an Order has a Customer Contact and a DeliveredTo Contact, thus there are two one-to-many associations between Order and Contact.

This is represented by declaring association roles using an optional knownas attribute, for example:

<assoc>
  <one src='Contact' knownas='Customer' required='true'/>
  <many src='Order'/>
</assoc>

<assoc>
  <one src='Contact' knownas='DeliveredTo'/>
  <many src='Order' knownas="ReceivedOrder"/>
</assoc>

You might notice that associations can be required as well as properties.

Set Ownership

The declaration of a one-to-many or many-to-many allow the declaration of an "owner" of the association. For example, if a Business is the "owner" in a one-to-many association with Products, then the Alchemist will generate methods on the Business class to create new instances of Product and add them to the set of Products implied by the association.

Set Access

A key feature of the GPO model is the way that sets are represented.

GPO can efficiently represent and manage sets with millions of object members, access to such sets return object derived from the java Iterator class - from a database viewpoint, these could be likened to CURSORS.

In example of a one-to-many association between Business and Products, a getProducts() method is generated for the Business class.

Set Lookup

Frequently, an application will need to access/lookup some specific member of a set based on some property value - accessing a specific Product for example.

When declaring an association, the many end of an association may be declared as classified and the property used for the classification is provided, for example:

classified="Name"

would lead to the generation of a getProductByName(String name) method.

GUI Hints

In addition to type restrictions already described, there is more information that is required in order to generate usable user interfaces. These are guihints, and are used to "hint" at interface requirements, for example:

<attr label='Address' type='java.lang.String' guihint='rows:3'/>

indicates that a multi-row text input box of 3 rows should be used to display and edit the property value, while:

<attr label="Price"
      type='java.lang.Double'
      guihint='numberformat:###,##0.00'
      formula="(sum $$OrderItem.$Price)"/>

Indicates the format that should be used to display the value of the property.

Notice that there is a significant difference between guihint and restriction, a restriction deals with the value of the property, while the guihint deals with the display of the value.

Formulas

You may have noticed in the above example the use of a formula declaration.

This is really far more than a pattern, it is a whole new idiom and you should check out the relevant whitepaper for more information.

That formulas can be declared for property values that navigate the object model is true breakthrough functionality, and dramatically increases the number of systems that can be fully generated.