ZK and JavATE

From Documentation
ZK and JavATE

Author
Andrea Mattioli, founder, JavATE
Date
September 15, 2009
Version
3.6.2 and later

Introduction

Nowadays application development is a matter of dealing with a large number of technologies, libraries, frameworks, etc. You typically have to put together things such as Hibernate or JPA with LDAP directories, content repositories and with ZK etc.

JavATE, following the principles of Domain Driven Design (DDD), tries to glue together all these things in a consistent way with special attention to reuse and modularity.

JavATE is itself modular. It is divided in sub-projects and you don't have to use the full-stack. You can decide to use only part of it and integrate with whatever you want even though most benefits can be obviously obtained using them together.

The basic module is called "DominATE" and deals with your application domain logic, your object model. It has implementations of the basic building blocks of DDD such as Entity, Repository and Specification.

On top of this there is the "ApplicATE" module. It is composed by a set of services that user interfaces can bind to so as to build a real application. The philosophy behind these services is that the most common way for interacting with an application is:

  • browse through a network of objects
  • once you have found the object you are interested in do something with it

So we developed interfaces and default implementation for:

  • Browsers, objects that enable you to navigate your object network
  • Commands, objects that allow you to do something, typically editing a domain entity or call a method on it

At the very top of the stack there is "GuidATE", the GUI driver. We implemented it using ZK that best matches the JavATE philosophy. With GuidATE we develop user interface views that bind to back-beans, the objects that provide real application functionality. Most of the time the back-beans will be ApplicATE services.

An example

As an example is worth 1000 words so let us put our hands on JavATE developing a very simple CRUD application. Obviously you can do more with JavATE than developing a CRUD application but it is sufficient for a little example like this.

This example is a short version of the basic example you can find on the JavATE site. Refer to it for details.

Create a simple Person class like the following:

public class Person extends EntityImpl {
        private String firstName;
        private String lastName;
        private Date birthDate;

        public String getFirstName() {
                return firstName;
        }

        public void setFirstName(String firstName) {
                this.firstName = firstName;
        }

        public String getLastName() {
                return lastName;
        }

        public void setLastName(String lastName) {
                this.lastName = lastName;
        }

	public Date getBirthDate() {
                return birthDate;
        }

        public void setBirthDate(Date birthDate) {
                this.birthDate = birthDate;
        }
		
        public static Repository<Long, Person> repository() {
                return RepositoryRegistry.instance().getRepository(Person.class);
        }
        
}

The EntityImpl base class already has a Long "id" property and a "version" property useful for optimistic locking purposes.

The static repository() method is there to retrieve an instance of a repository useful to access Person objects. It's not mandatory but I often find it useful.

Create a corresponding table on your database, map them with Hibernate, and configure hibernate.cfg.xml as usual.

Then develop a service factory with a method in order to create a person browser:

public class ExampleServiceFactory extends AbstractServiceFactory {

	public ListBrowser<Long, Person> createPersonBrowser() {
	    return new ListBrowserImpl<Long, Person>(Person.repository());
	}
        
}

We are using an instance of the ListBrowser interface. This kind of browser is the simplest and most common available. It is thought for the purpose of navigating through a list of objects.

The service is parametrized by two classes: Long and Person. The latter is the class of the objects we are going to browse, the former is its id class.

Then you have to configure the application, so it knows how to create services and repositories, with a property file as the following:

it.amattioli.guidate.repositoryFactoryClass = it.amattioli.dominate.hibernate.HibernateRepositoryFactory
it.amattioli.guidate.serviceFactoryClass = it.amattioli.example.ExampleServiceFactory
it.amattioli.guidate.applicateSessionClass = it.amattioli.applicate.sessions.ApplicateSession
it.amattioli.guidate.applicateSessionVariable = applicateSession

and create the .zul file that accesses the browser and shows its content

<window id="personBrowserWindow"
	    title="Persons" 
	    border="normal" 
	    width="500px"
	    apply="it.amattioli.guidate.containers.BackBeanComposer">
	<custom-attributes backBean="personBrowser"/>

	<browserListbox id="personList" rows="5" width="99%">
		<listhead>
			<browserListheader label="First Name" width="40%"/>
			<browserListheader label="Last Name"  width="40%"/>
			<browserListheader label="Birth Date" width="20%"/>
		</listhead>
		<listitemPrototype>
			<labelListcell propertyName="firstName"/>
			<labelListcell propertyName="lastName"/>
			<labelListcell propertyName="birthDate" conversionFormat="dd/MM/yyyy"/>
		</listitemPrototype>
	</browserListbox>
</window>

Have a look at the window. It has a custom-attribute called backBean that is used to say which is the object it has to bind to. In our service factory we have a createPersonBrowser() method, consequently its value will be "personBrowser".

Don't forget standard ZK configurations in web.xml and zk.xml and you have done it: build, deploy on your application server and point your browser to the newest created zul page so as to see the list of the person objects that are in your database.

If you want to edit directly this list you can use a RepositoryEditor service. Add a factory method as the following in the service factory

        public RepositoryEditor<Long,Person> createPersonEditor() {
		RepositoryEditor<Long, Person> editor = new RepositoryEditor<Long,Person>(Person.repository(), Person.class);
		return TransactionalCommandContext.newTransaction(editor);
	}

and create the following zul page:

	<window id="personEditorWindow"
	                title="persons" 
	                border="normal" 
	                width="250px"
	                apply="it.amattioli.guidate.containers.CommandComposer">

		<custom-attributes backBean="personEditor"/>

		<toolbar>
			<toolbarbutton label="Add"         width="70px" apply="it.amattioli.guidate.editing.AddRowComposer"/>
			<toolbarbutton label="Remove"  width="70px" apply="it.amattioli.guidate.editing.DeleteRowComposer"/>
		</toolbar>

		<editorListbox id="exampleList" rows="5" width="99%">
		        <listitemPrototype>
				<listcell>
					<textProperty propertyName="firstName"/>
                                </listcell>
                                <listcell>
                                        <textProperty propertyName="lastName"/>
				</listcell>
                                <listcell>
                                        <dateProperty propertyName="birthDate"/>
				</listcell>
			</listitemPrototype>
		</editorListbox>

		<hbox>
			<button label="Ok"     width="70px" forward="onDoCommand"/>
			<button label="Cancel" width="70px" forward="onCancelCommand"/>
		</hbox>

	</window>

Conclusion

In this article I have showed you just a very small subset of the JavATE features. If you are interested in JavATE have a look at the web site. You'll find two examples and some documentation. And don't forget to leave your opinions on the project forum.



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.