ZK Demo Project

AutoBusLogicZK is a simple project that demonstrates the use of ABL's transactional business logic engine with the ZK framework.  This page explains how to load the demo and the required runtime.  To load the entire product (with samples and documentation), see the downloads page.

AutoBusLogicZK uses the same database schema, and the same business logic, as the basic AutoBusLogic. However, unlike the basic demo, which is built using straight JSP, this demo is built entirely using ZK as the GUI framework.


Start by downloading the ZK demo from the download area:

Once you have the file, you'll want to extract it, which will result in a directory named AutoBusLogicZK. This directory is a ZK project that can be imported into Eclipse, or any other IDE. We'll focus on Eclipse here, but the process should be similar in other environments.

Loading the project into Eclipse

Before doing this, you'll want to make sure that you have the ZK Studio plugin installed, since it does make life easier. It is available from the ZK web site.

You will also require JDK 1.5 or later. This demo does not work with JDK 1.4 or earlier.

To load the project into Eclipse:
  • select File -> Import
  • select General -> Existing Projects into Workspace
  • select the BusLogicDemoZK directory
  • finish the import
  • assign the application to a server (we use Tomcat 7.0, but any server should do)
  • start the server
  • connect to http://localhost:8080/BusLogicDemoZK
At that point, you should see a screen similar to:

What does the demo do?

The demo is a simplistic (but not trivial) order management application. In this application, you can:
  • navigate from customer to customer using the drop-down at the top
  • change a customer's credit limit
  • create and delete orders
  • make an order paid or unpaid
  • edit an order's notes
  • reassign an order to a different customer
  • create and delete order items
  • change an order item's quantity
  • change an order item's product

Note that this app has no "Save" button: all changes are applied immediately. When editing text in a text box, just tab out of the box, or click out of it, and the change will be applied.
This was done to keep the interface simple, but you are of course not required to use the same approach in your own applications.

Whenever you edit something (e.g. change the customer's credit limit, add an item to an order, change an item's quantity, etc...), the transactional business logic fires when the transaction is committed. If it succeeds, the GUI is then notified to refresh whatever data has been changed.

A few things to try

Once you are in the demo, we suggest you try the following:

Mark an order as paid

If you check the "Paid" checkbox for an order, you will notice that the customer's balance will decrease by the amount of the order. That's because only unpaid orders count towards a customer's balance.

Reassign an order from one customer to another

If you expand an order (using the + icon in the left column), you'll see that each order has a drop-down titled "Reassign to customer...". If you select a customer from that drop-down, the order will then be moved to that customer, and will therefore disappear from the current view. The current customer's balance will be decreased

Edit a customer's credit limit

If you change a customer's credit limit to be less than the balance, you will get a constraint violation, and the transaction will be rolled back.

Change an order item's product

If you change the product for an order item (e.g. from a shovel to a hammer), you'll see that the item's amount, the order's total, and the customer's balance (if the order is unpaid) will be updated.

While this may all seem simple, there is actually quite a bit going on here. In this particular case, the following rules are involved:


public void deriveProductPrice() { }

 The product's price will be copied to the order item's productPrice.

@Formula("productPrice * qtyOrdered")

public void deriveAmount() { }

 The order item's amount will then be recomputed, since productPrice has changed.


public void deriveAmountTotal() { }

 The order's amountTotal will then be recomputed, since one of its items' amount has changed.

@Sum("purchaseorders.amountTotal where paid = false")

public void deriveBalance() { }

 If the order is not paid, then the customer's balance will be recomputed, since one of the unpaid orders' amountTotal has changed.

@Constraint(value="balance <= creditLimit",

    errorMessage="Customer balance exceeds credit limit")

public void constraintCreditLimit() { }

 Finally, the customer's freshly-updated balance will be compared to the credit limit, and, if it exceeds it, the transaction will be rolled back.

Notice that we never specifically invoked any of these rules. They were invoked automatically as part of the commit process. And they were invoked in the correct order, because the logic engine understands the dependencies between them.

This means that the application doesn't have to know (or care) about the rules, and can just focus on the task at hand (allowing the user to manipulate data), rather than worry about enforcing the underlying business logic.