Prevalence: Transparent, Fault-Tolerant Object Persistence
Pages: 1, 2, 3, 4, 5
Adding the Business Objects
The prevalent system is now ready to have some business objects
associated with it. The first business class to add is
Item. Right-click on the
PrevalentOrderSystem class in the Eclipse
Package Explorer and select Prevayler ->
Create Business Object. Note that you will only see the
Prevayler option on the context menu if you select
the correct object in the Package Explorer: you need to select the
class, not the source file (see Figure 5).

Figure 5. Adding a business object
The Create Business Object dialogue opens. This allows you to specify the name of a BO class, and to specify whether the prevalent system will contain a single object or a list of objects. Enter Item in the BO Class Name box and select List, as you want the system to be able to contain many items (see Figure 6). Enter items in the "field name" box.

Figure 6. Specifying details of the business object
Click Finish and a new class, Item,
is added to the project. The PrevalentSystem class is
altered so that it has a field of the type ArrayList, and
methods to add a new Item, retrieve an
Item by id, and remove an
Item. The addItem method is shown in the
listing below. This method uses the nextItemID field
to ensure that a unique id is added to the
Item before storing in the ArrayList. You
will need to modify the auto-generated code slightly, as shown in
the listing below--this version passes a reference to an
Item into the method and then sets its
id. The listing also shows a method,
getItems, which returns the whole list--this is not
generated by Preclipse, so you need to add it yourself.
public class PrevalentOrderSystem implements Serializable {
private List items = new ArrayList();
private long nextItemID = 1;
public PrevalentOrderSystem() {
super();
}
public Item addItem(Item newItem) {
newItem.setID(nextItemID++);
this.items.add(newItem);
return newItem;
}
public List getItems(){
return items;
}
// other methods omitted for brevity...
}
The Item class, at this stage, has only an
id field, which will be used to identify particular
objects stored in the prevalent system. You need to add additional
fields and methods to match the specification in Figure 1. The
completed Item class is as follows (with
getters/setters omitted for brevity). Note that the id
field is not set in the constructor--in this example,
ids are only set when an object is made persistent by
a transaction.
public class Item implements Serializable {
private long id;
private int currentStock;
private double price;
private long itemCode;
public Item() {
this.setCurrentStock(100);
}
public double getPostage() {
return 0.0;
}
public void reStock(int quantity) {
setCurrentStock(getCurrentStock() + quantity);
}
public void order(int quantity)
throws InsufficientStockException{
if (getCurrentStock() >= quantity) {
setCurrentStock(getCurrentStock() - quantity);
} else {
throw new InsufficientStockException
(currentStock);
}
}
public String toString() {
return (id + " - " + this.getClass() +
":" + currentStock + " in stock");
}
// getters/setters omitted...
}
The Item class throws a custom exception,
InsufficientStockException, which can be added to the
project as an ordinary Java class, not using any Prevayler-specific
options.
public class InsufficientStockException extends Exception {
private int currentStock;
public InsufficientStockException(int currentStock){
this.currentStock = currentStock;
}
public String toString(){
return (super.toString() + ": current stock level is "
+ currentStock);
}
// getters/setters omitted...
}
The subclasses of Item can now be added to the
project as ordinary Java classes--they become persistent BO
classes because they are subclasses of an existing BO class. An
instance of BookItem, for example, will inherit its
id field from the superclass.
public class BookItem extends Item {
private String title;
private String authors;
private String publisher;
public BookItem() {
}
public BookItem(double price, String title, String
authors, String publisher) {
this.setPrice(price);
this.setTitle(title);
this.setAuthors(authors);
this.setPublisher(publisher);
}
public double getPostage() {
return (getPrice() * 0.10);
}
public String toString(){
return(super.toString() + ":" + this.title);
}
// getters/setters omitted...
}
public class SoftwareItem extends Item {
private String title;
private String version;
public SoftwareItem() {
}
public SoftwareItem(double price, String title, String version){
this.setPrice(price);
this.setTitle(title);
this.setVersion(version);
}
public double getPostage(){
return 2.50;
}
public String toString(){
return(super.toString() + ":" + this.title);
}
// getters/setters omitted...
}
public class MultipackItem extends Item {
private Item item;
private int multiple;
private double discount;
public MultipackItem(){}
public MultipackItem(Item item, int multiple, double
discount) {
this.setItem(item);
this.setMultiple(multiple);
this.setDiscount(discount);
}
public double getPrice() {
double packPrice =
(getItem().getPrice() *
getMultiple() * (1 - getDiscount()));
return packPrice;
}
public double getPostage() {
double packPostage = (getItem().getPostage() *
getMultiple() * 0.5);
return packPostage;
}
public String toString(){
return(super.toString() + "(" +
this.item.toString() + ")");
}
// getters/setters omitted...
}