Prevalence: Transparent, Fault-Tolerant Object Persistence
Pages: 1, 2, 3, 4, 5
Completing the System
So far you have created a system that stores objects based on a
single class hierarchy. Adding the remaining BO classes and
transactions will show how a prevalent system deals with associated
classes. First, add the class OrderLine to the project
as an ordinary Java class:
import java.io.Serializable;
public class OrderLine implements Serializable {
private Item item;
private int quantity;
private double linePrice;
private double linePostage;
public OrderLine(){
}
public OrderLine(Item item, int quantity){
this.setItem(item);
this.setQuantity(quantity);
this.setLinePrice(item.getPrice() * quantity);
this.setLinePostage(item.getPostage() * quantity);
}
// getters/setters omitted...
}
Now add a new BO class called Order, in the same
way that you added the Item BO class. Appropriate fields
and methods are added to PrevalentOrderSystem. Add a
getOrders method similar to the getItems
method you added previously. Modify the generated Order
class as follows:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Order implements Serializable {
private long id;
private List orderLines;
public Order(){
}
public Order(long id) {
this.id = id;
orderLines = new ArrayList();
}
public void newOrderLine(Item item, int quantity) {
try {
item.order(quantity);
OrderLine ol = new OrderLine(item, quantity);
orderLines.add(ol);
} catch (Exception e) {
e.printStackTrace();
}
}
public double getTotalCost() {
double totalCost = 0.0;
for (Iterator itr = orderLines.iterator();
itr.hasNext();) {
OrderLine ol = (OrderLine) itr.next();
totalCost = ol.getLinePrice() +
ol.getLinePostage();
}
return totalCost;
}
// getters/setters omitted...
public String toString(){
return(id + " - " + this.getClass() + ":Cost $" +
this.getTotalCost());
}
}
Now add a new Create transaction for the Order BO class as you
did for the Item class. Do not select the
orderlines field for the transaction constructor in
the dialogue. Modify the executeAndQuery method as
follows:
public Object executeAndQuery(Object prevalentSystem, Date
executionTime) throws Exception {
Order or = ((PrevalentOrderSystem)prevalentSystem).addOrder();
return or;
}
The addOrder method in
PrevalentOrderSystem does not need to be modified--it simply creates a new Order object with the next
available id, and adds it to the system. No other
initialization is required--an Order is initially empty.
public Order addOrder() {
Order newOrder = new Order(nextOrderID++);
this.orders.add(newOrder);
return newOrder;
}
An empty Order is not very interesting--we need a
transaction to allow an Item to be added to an
Order. Add a new transaction to the Order
BO--a Change transaction, this time. The transaction should be
called OrderAddItemTranscation. You need to select at
least one field in the Create Transaction dialogue, shown in Figure
12. Select the orderlines field. This is not really
appropriate (as the transaction that Preclipse generates is aimed
at simply changing the value of a field, and you will be doing
something slightly different here), but you need to select at least
one field for the dialogue to complete.

Figure 12. Creating a Change transaction
Modify the created transaction to the following:
import java.util.Date;
import org.prevayler.TransactionWithQuery;
public class OrderAddItemTransaction
implements TransactionWithQuery {
private long id;
private long itemId;
private int quantity;
public OrderAddItemTransaction(long id, long itemId,
int quantity) {
this.id = id;
this.itemId = itemId;
this.quantity = quantity;
}
public OrderAddItemTransaction() {
}
public Object executeAndQuery(Object prevalentSystem,
Date executionTime throws Exception {
Order order = ((PrevalentOrderSystem)prevalentSystem).
getOrder(id);
Item item = ((PrevalentOrderSystem)prevalentSystem).
getItem(itemId);
order.newOrderLine(item, quantity);
item.order(quantity);
return order;
}
}
Note that this transaction changes the data in two ways--the
Order is updated with the new Orderline,
and the stock for the Item is updated. Finally, add a
new Change transaction for the Item BO class, called
ItemRestockTransaction, selecting the
currentStock field only in the dialogue. Modify the
created transaction to the following:
import java.util.Date;
import org.prevayler.TransactionWithQuery;
public class ItemRestockTransaction
implements TransactionWithQuery {
private long id;
private int newStock;
public ItemRestockTransaction(long id, int newStock) {
this.id = id;
this.newStock = newStock;
}
public ItemRestockTransaction() {
}
public Object executeAndQuery(Object prevalentSystem,
Date executionTime) throws Exception {
Item item = ((PrevalentOrderSystem)prevalentSystem).
getItem(id);
item.reStock(newStock);
return item;
}
}