PROGRAM 1
// Filename: Post1.java, Post2.java Author: Anthony F. Ortiz
// Since there are security restrictions for these two applets, I
// included equivalent application versions, Post3.java, Post4.java.
// However, both appletviewer and Netscape 3.0 will work for these
// applets.
// Filename: Post3.java Author: Anthony F. Ortiz
// This is the main version 1 of the post application. It focuses on
// materialization and dematerialization of a ProductSpecification.
import java.awt.*;
public class Post3 extends Frame
{
private ProductSpecificationProxy psProxy;
private BrokerServer bServer = BrokerServer.getInstance ();
private Label postLabel, oidLabel, descriptionLabel, priceLabel, upcLabel, objectLabel;
private TextField oidText, descriptionText, priceText, upcText;
private Button changeButton, commitButton, displayButton, insertButton, removeButton, rollbackButton;
// draws the interface.
public static void main (String [] args)
{
Frame p = new Post3 ();
p.resize (640, 480);
p.setTitle ("Post3");
p.show ();
}
public Post3 ()
{
int height = 480 / 9;
// CSU-Hayward colors
setBackground (Color.red);
setForeground (Color.black);
Font font = new Font ("Courier", Font.BOLD, 12);
setFont (font);
setLayout (null);
postLabel = new Label ("Post");
postLabel.reshape (10, 1 * height, 250, 25);
add (postLabel);
oidLabel = new Label ("Enter an psOID:");
oidLabel.reshape (10, 2 * height, 200, 25);
add (oidLabel);
oidText = new TextField ();
oidText.reshape (220, 2 * height, 200, 25);
add (oidText);
descriptionLabel = new Label ("Enter a description:");
descriptionLabel.reshape (10, 3 * height, 200, 25);
add (descriptionLabel);
descriptionText = new TextField ();
descriptionText.reshape (220, 3 * height, 200, 25);
add (descriptionText);
priceLabel = new Label ("Enter a price:");
priceLabel.reshape (10, 4 * height, 200, 25);
add (priceLabel);
priceText = new TextField ();
priceText.reshape (220, 4 * height, 200, 25);
add (priceText);
upcLabel = new Label ("Enter a UPC:");
upcLabel.reshape (10, 5 * height, 200, 25);
add (upcLabel);
upcText = new TextField ();
upcText.reshape (220, 5 * height, 200, 25);
add (upcText);
changeButton = new Button ("Change");
changeButton.reshape (430, 2 * height, 200, 25);
add (changeButton);
insertButton = new Button ("Insert");
insertButton.reshape (430, 3 * height, 200, 25);
add (insertButton);
removeButton = new Button ("Remove");
removeButton.reshape (430, 4 * height, 200, 25);
add (removeButton);
displayButton = new Button ("Display");
displayButton.reshape (430, 5 * height, 200, 25);
add (displayButton);
commitButton = new Button ("Commit");
commitButton.reshape (220, 6 * height, 200, 25);
add (commitButton);
rollbackButton = new Button ("Rollback");
rollbackButton.reshape (430, 6 * height, 200, 25);
add (rollbackButton);
objectLabel = new Label ("PS Record!");
objectLabel.reshape (220, 7 * height, 200, 25);
add (objectLabel);
}
// Close window.
public boolean handleEvent (Event event)
{
if (event.id == Event.WINDOW_DESTROY)
{
System.exit (0);
}
return (super.handleEvent (event));
}
// These are the actions taken by the different buttons. The
// actions include, change ps, commit changes, display ps, insert ps,
// remove ps, and rollback changes.
public boolean action (Event event, Object object)
{
if (event.target == changeButton)
{
psProxy = new ProductSpecificationProxy (oidText.getText ());
objectLabel.setText ("Change ps: " + descriptionText.getText () + " " + priceText.getText () + " " + upcText.getText ());
if (descriptionText.getText () != "")
{
psProxy.setDescription (descriptionText.getText ());
}
if (priceText.getText () != "")
{
psProxy.setPrice ((float) new Double (priceText.getText ()).doubleValue ());
}
if (upcText.getText () != "")
{
psProxy.setUPC (Integer.parseInt (upcText.getText ()));
}
return true;
}
else if (event.target == commitButton)
{
objectLabel.setText ("Commit:");
oidText.setText ("");
descriptionText.setText ("");
priceText.setText ("");
upcText.setText ("");
bServer.commit ();
return true;
}
else if (event.target == displayButton)
{
psProxy = new ProductSpecificationProxy (oidText.getText ());
descriptionText.setText (psProxy.getDescription ());
priceText.setText ("" + psProxy.getPrice ());
upcText.setText ("" + psProxy.getUPC ());
objectLabel.setText ("Display ps: " + descriptionText.getText () + " " + priceText.getText () + " " + upcText.getText ());
return true;
}
else if (event.target == insertButton)
{
String anOID = RandomNumberGenerator.getRandomNumber ();
psProxy = new ProductSpecificationProxy (anOID, Integer.parseInt (upcText.getText ()), (float) new Double (priceText.getText ()).doubleValue (), descriptionText.getText ());
objectLabel.setText ("Insert ps: " + descriptionText.getText () + " " + priceText.getText () + " " + upcText.getText ());
oidText.setText (anOID);
return true;
}
else if (event.target == removeButton)
{
psProxy = new ProductSpecificationProxy (oidText.getText ());
psProxy.remove ();
descriptionText.setText (psProxy.getDescription ());
priceText.setText ("" + psProxy.getPrice ());
upcText.setText ("" + psProxy.getUPC ());
objectLabel.setText ("Remove ps: " + descriptionText.getText () + " " + priceText.getText () + " " + upcText.getText ());
return true;
}
else if (event.target == rollbackButton)
{
objectLabel.setText ("Rollback: ");
oidText.setText ("");
descriptionText.setText ("");
priceText.setText ("");
upcText.setText ("");
bServer.rollback ();
psProxy.reset ();
return true;
}
else
{
return false;
}
}
}
// Filename: Post4.java Author: Anthony F. Ortiz
// This is the main version 2 of the post application. It focuses on
// materialization of a ProductSpecification, SaleLineItem, and Sale.
import java.applet.Applet;
import java.awt.*;
public class Post4 extends Frame
{
private ProductSpecificationProxy psProxy;
private SaleLineItemProxy sliProxy;
private SaleProxy sProxy;
private Label psLabel, sliLabel, sLabel, resultsLabel, postLabel;
private TextField psText, sliText, sText;
private Button psButton, sliButton, sButton;
// draws the interface.
public static void main (String [] args)
{
Frame p = new Post4 ();
p.resize (640, 480);
p.setTitle ("Post4");
p.show ();
}
public Post4 ()
{
int height = 480 / 7;
// CSU-Hayward colors
setBackground (Color.red);
setForeground (Color.black);
Font font = new Font ("Courier", Font.BOLD, 12);
setFont (font);
setLayout (null);
postLabel = new Label ("Post");
postLabel.reshape (10, 1 * height, 250, 25);
add (postLabel);
psLabel = new Label ("Enter an psOID:");
psLabel.reshape (10, 2 * height, 200, 25);
add (psLabel);
psText = new TextField ();
psText.reshape (220, 2 * height, 200, 25);
add (psText);
psButton = new Button ("Display ProductSpecification");
psButton.reshape (430, 2 * height, 200, 25);
add (psButton);
sliLabel = new Label ("Enter an sliOID:");
sliLabel.reshape (10, 3 * height, 200, 25);
add (sliLabel);
sliText = new TextField ();
sliText.reshape (220, 3 * height, 200, 25);
add (sliText);
sliButton = new Button ("Display SaleLineItem");
sliButton.reshape (430, 3 * height, 200, 25);
add (sliButton);
sLabel = new Label ("Enter an sOID:");
sLabel.reshape (10, 4 * height, 200, 25);
add (sLabel);
sText = new TextField ();
sText.reshape (220, 4 * height, 200, 25);
add (sText);
sButton = new Button ("Display Sale");
sButton.reshape (430, 4 * height, 200, 25);
add (sButton);
resultsLabel = new Label ("Results go here!");
resultsLabel.reshape (220, 5 * height, 400, 25);
add (resultsLabel);
}
// Close window.
public boolean handleEvent (Event event)
{
if (event.id == Event.WINDOW_DESTROY)
{
System.exit (0);
}
return (super.handleEvent (event));
}
// These are the actions taken by the different buttons. The
// actions include, display ProductSpecification (description, price,
// and upc), display SaleLineItem (total of a SaleLineItem), and
// display Sale (total of one or more SaleLineItems).
public boolean action (Event event, Object object)
{
if (event.target == psButton)
{
psProxy = new ProductSpecificationProxy (psText.getText ());
resultsLabel.setText (psProxy.getDescription () + " " + psProxy.getPrice () + " " + psProxy.getUPC ());
return true;
}
else if (event.target == sliButton)
{
sliProxy = new SaleLineItemProxy (sliText.getText ());
resultsLabel.setText ("The subtotal for this sale line item is " + sliProxy.subtotal () + ".");
return true;
}
else if (event.target == sButton)
{
sProxy = new SaleProxy (sText.getText ());
resultsLabel.setText ("The total for this sale is " + sProxy.total () + ".");
return true;
}
else
{
return false;
}
}
}
// Filename: BrokerServer.java Author: Anthony F. Ortiz
// This file contains the BrokerServer. All brokers must register
// themselves with it (in PFWBroker). The BrokerServer saves a
// broker after it registers in a vector. When a BrokerServer
// does a commit or rollback, each broker in the vector is called upon to
// perform the actual commit and rollback on the cache and database.
import java.util.*;
public class BrokerServer
{
private static BrokerServer instance = new BrokerServer ();
private Vector brokers = new Vector ();
private Vector oids = new Vector ();
// Private constructor (singelton).
private BrokerServer ()
{
}
// Get the only instance of BrokerServer (singelton).
public static BrokerServer getInstance ()
{
return instance;
}
// Register brokers with the BrokerServer.
public void register (String anOID, Object broker)
{
brokers.addElement (broker);
oids.addElement (anOID);
}
// Commit deletes, inserts, and updates from the cache and
// database.
public void commit ()
{
int i = 0;
while (brokers.size () - 1 >= i)
{
PFWBroker pfwBroker = (PFWBroker) brokers.elementAt (i);
pfwBroker.commit ((String) oids.elementAt (i));
i++;
}
}
// Rollback deletes, inserts, and updates from the cache and
// database.
public void rollback ()
{
int i = 0;
while (brokers.size () - 1 >= i)
{
PFWBroker pfwBroker = (PFWBroker) brokers.elementAt (i);
pfwBroker.rollback ((String) oids.elementAt (i));
i++;
}
}
}
// Filename: FilePFWBroker.java Author: Anthony F. Ortiz
// This file contains the FilePFWBroker. It will not be used in the
// project.
public abstract class FilePFWBroker extends PFWBroker
{
// This method will not be used in the project.
public Object materializeWith (String anOID)
{
Object obj = new Object ();
return obj;
}
// Abstract method.
public abstract String objectAsRecord (String anOID, Object obj);
}
// Filename: IProductSpecification.java Author: Anthony F. Ortiz
// This file contains the interface for ProductSpecifcation and its
// Proxy.
public interface IProductSpecification
{
// Abstract methods (interface).
public String getDescription ();
public float getPrice ();
public int getUPC ();
public void setDescription (String change);
public void setPrice (float change);
public void setUPC (int change);
}
// Filename: ISale.java Author: Anthony F. Ortiz
// This file contains the interface for Sale and its Proxy.
public interface ISale
{
// Abstract methods (interface).
public float getBalance ();
public String getDate ();
public float total ();
}
// Filename: ISaleLineItem.java Author: Anthony F. Ortiz
// This file contains the interface for SaleLineItem and its
// Proxy.
public interface ISaleLineItem
{
// Abstract method (interface).
public float subtotal ();
}
// Filename: ObjectCache.java Author: Anthony F. Ortiz
// This file contains the cache for the ProductSpecification,
// SaleLineItem, and Sale objects. The PFWBroker class has a handle to
// it. Two hashtables hold the objects and the states of the cached
// objects.
import java.util.Hashtable;
public class ObjectCache
{
private Hashtable objects = new Hashtable ();
private Hashtable states = new Hashtable ();
// Add object and it's state to the cache.
public void add (String anOID, Object obj, String state)
{
objects.put (anOID, obj);
states.put (anOID, state);
}
// Get the object at key, anOID.
public Object find (String anOID)
{
return objects.get ((Object) anOID);
}
// Returns true if key is not in the cache. Otherwise, it returns
// false.
public boolean isEmpty (String anOID)
{
return objects.contains (anOID);
}
// Remove the object and state from the cache at key, anOID.
public void remove (String anOID)
{
objects.remove (anOID);
states.remove (anOID);
}
// Get the object's state at key, anOID.
public String getState (String anOID)
{
return (String) states.get (anOID);
}
}
// Filename: Payment.java Author: Anthony F. Ortiz
// This file is used by the Sale class. It's main attribute is amount
// which is what the customer gives the cashier. It won't be needed
// for the project.
public class Payment
{
private float amount;
// Constructor.
public Payment (float cashTendered)
{
this.amount = cashTendered;
}
// Get the amount the customer gives the cashier.
public float getAmount ()
{
return amount;
}
}
// Filename: PFWBroker.java Author: Anthony F. Ortiz
// This file contains the top level broker. The RelationalPFWBroker
// inherits from it. It materializes objects not cached or returns them
// if they are. It also performs rollback and commits on the cache
// and the database.
public abstract class PFWBroker
{
protected ObjectCache cache = new ObjectCache ();
protected BrokerServer bServer;
protected String table = new String ();
protected final String newclean = "newclean";
protected final String newdirty = "newdirty";
protected final String oldclean = "oldclean";
protected final String olddirty = "olddirty";
protected final String newdeleted = "newdeleted";
protected final String olddeleted = "olddeleted";
// Register broker with the BrokerServer, see if object is in the
// cache. If it is in the cache, return it. Otherwise, materialize
// it (do a query to the database, cache it, and return it).
public Object objectWith (String anOID)
{
bServer = BrokerServer.getInstance ();
bServer.register (anOID, this);
Object obj = inCache (anOID);
if (obj != null)
{
return obj;
}
else
{
return materializeWith (anOID);
}
}
// Return the cached object if it is in the cache.
public Object inCache (String anOID)
{
return cache.find (anOID);
}
// Add 'oldclean' to the cache when a new object is inserted from
// the database.
public void addOldClean (String anOID, Object obj)
{
if (obj != null)
{
cache.add (anOID, obj, oldclean);
}
}
// Add 'newclean' to the cache when a new object is inserted from
// the application.
public void addNewClean (String anOID, Object obj)
{
cache.add (anOID, obj, newclean);
}
// Add 'olddirty' or 'newdirty' to the cache when an object is
// updated.
public void addOldDirtyorNewDirty (String anOID, Object obj)
{
if (cache.getState (anOID) == oldclean || cache.getState (anOID) == olddirty)
{
cache.add (anOID, obj, olddirty);
}
else if (cache.getState (anOID) == newclean || cache.getState (anOID) == newdirty)
{
cache.add (anOID, obj, newdirty);
}
}
// Add 'olddeleted' or 'newdeleted' to the cache when an object is
// deleted.
public void addOldDeletedorNewDeleted (String anOID, Object obj)
{
if (cache.getState (anOID) == oldclean || cache.getState (anOID) == olddirty)
{
cache.add (anOID, obj, olddeleted);
}
else if (cache.getState (anOID) == newclean || cache.getState (anOID) == newdirty)
{
cache.add (anOID, obj, newdeleted);
}
}
// Commit the deletes, inserts, and updates in the cache and
// database.
public void commit (String anOID)
{
Object obj = new Object ();
PostDB db = PostDB.getInstance ();
String query = new String ();
if (cache.getState (anOID) == newclean)
{
obj = cache.find (anOID);
addOldClean (anOID, obj);
query = objectAsRecord (anOID, obj);
db.update ("insert into " + table + " values " + query);
}
else if (cache.getState (anOID) == newdirty) // same as 'olddirty'.
{
obj = cache.find (anOID);
addOldClean (anOID, obj);
query = objectAsRecord (anOID, obj);
db.update ("insert into " + table + " values " + query);
}
else if (cache.getState (anOID) == olddirty)
{
obj = cache.find (anOID);
addOldClean (anOID, obj);
db.update ("delete from " + table + " where OID = " + "'" + anOID + "'");
query = objectAsRecord (anOID, obj);
db.update ("insert into " + table + " values " + query);
}
else if (cache.getState (anOID) == newdeleted)
{
cache.remove (anOID);
}
else if (cache.getState (anOID) == olddeleted)
{
cache.remove (anOID);
db.update ("delete from " + table + " where OID = " + "'" + anOID + "'");
}
}
// Rollback the deletes, inserts, and updates in the cache and
// database.
public void rollback (String anOID)
{
if (cache.getState (anOID) == newclean ||
cache.getState (anOID) == newdirty ||
cache.getState (anOID) == olddirty ||
cache.getState (anOID) == newdeleted ||
cache.getState (anOID) == olddeleted)
{
cache.remove (anOID);
}
}
// Abstract method.
public abstract Object materializeWith (String anOID);
// Abstract method.
public abstract String objectAsRecord (String anOID, Object obj);
}
// Filename: PostDB.java Author: Anthony F. Ortiz
// This file contains the class which will allow the relational database
// broker to execute SQL queries (select, insert, and delete). It is
// a singelton.
import java.net.URL.*;
import exjava.math.*;
import exgwe.sql.*;
import exjava.sql.*;
public class PostDB
{
private static PostDB instance = new PostDB ();
private String url = "jdbc:mysql://gold.mcs.csuhayward.edu:3333/postDB";
private String driverName = "exgwe.sql.gweMysqlDriver";
private String dbuser = "6310";
private String dbpass = "6310";
private Connection con = null;
private Statement stmt = null;
private ResultSet rs = null;
// Private constructor (singelton).
private PostDB ()
{
}
// Get the only instance of PostDB (singelton).
public static PostDB getInstance ()
{
return instance;
}
// Get ResultSet from a sql query.
public ResultSet execute (String query)
{
try
{
Class.forName (driverName);
con = DriverManager.getConnection (url, dbuser, dbpass);
stmt = con.createStatement ();
stmt.execute(query);
rs = stmt.getResultSet ();
//stmt.close ();
//con.close ();
if (rs.next () == false)
{
// This is for objects that are not in the database.
rs = null;
}
return rs;
}
catch (Exception e)
{
System.out.print (e);
}
return null;
}
// Update database (insert or delete).
public void update (String query)
{
try
{
Class.forName (driverName);
con = DriverManager.getConnection (url, dbuser, dbpass);
stmt = con.createStatement ();
stmt.executeUpdate(query);
//stmt.close ();
//con.close ();
}
catch (Exception e)
{
System.out.println (e);
}
}
}
// Filename: ProductSpecification.java Author: Anthony F. Ortiz
// This file contains one of the 3 realSubjects, ProductSpecification.
// A ProductSpecification has 3 attributes, upc, price, and description.
public class ProductSpecification implements IProductSpecification
{
private int upc = 0;
private float price = 0;
private String description = "";
// Constructor.
public ProductSpecification (int upc, float price, String description)
{
this.upc = upc;
this.price = price;
this.description = description;
}
// Get upc.
public int getUPC ()
{
return upc;
}
// Get price.
public float getPrice ()
{
return price;
}
// Get description.
public String getDescription ()
{
return description;
}
// Set upc.
public void setUPC (int change)
{
upc = change;
}
// Set price.
public void setPrice (float change)
{
price = change;
}
// Set description.
public void setDescription (String change)
{
description = change;
}
}
// Filename: ProductSpecificationProxy.java Author: Anthony F. Ortiz
// This file contains the proxy for SaleLineItem.
public class ProductSpecificationProxy extends VirtualProxy implements IProductSpecification
{
// Constructor.
public ProductSpecificationProxy (String anOID)
{
OID = anOID;
}
// Constructor (inserts, newclean).
public ProductSpecificationProxy (String anOID, int upc, float price, String description)
{
OID = anOID;
PFWBroker pfwBroker = (PFWBroker) getBroker ();
ProductSpecification aProductSpec = new ProductSpecification (upc, price, description);
pfwBroker.addNewClean (OID, aProductSpec);
BrokerServer bServer = BrokerServer.getInstance ();
bServer.register (anOID, pfwBroker);
}
// Get description from ProductSpecification (realSubject).
public String getDescription ()
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
return aProductSpec.getDescription ();
}
// Get price from ProductSpecification (realSubject).
public float getPrice ()
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
return aProductSpec.getPrice ();
}
// Get upc from ProductSpecification (realSubject).
public int getUPC ()
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
return aProductSpec.getUPC ();
}
// Create broker for ProductSpecifationProxy.
public Object createBroker ()
{
return ProductSpecificationRelationalBroker.getInstance ();
}
// Set description for ProductSpecification (realSubject).
public void setDescription (String change)
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
aProductSpec.setDescription (change);
PFWBroker pfwBroker = (PFWBroker) getBroker ();
pfwBroker.addOldDirtyorNewDirty (OID, aProductSpec);
}
// Set price for ProductSpecification (realSubject).
public void setPrice (float change)
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
aProductSpec.setPrice (change);
PFWBroker pfwBroker = (PFWBroker) getBroker ();
pfwBroker.addOldDirtyorNewDirty (OID, aProductSpec);
}
// Set upc for ProductSpecification (realSubject).
public void setUPC (int change)
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
aProductSpec.setUPC (change);
PFWBroker pfwBroker = (PFWBroker) getBroker ();
pfwBroker.addOldDirtyorNewDirty (OID, aProductSpec);
}
// Set realSubject to null. This solves the rollback, set problem.
public void reset ()
{
realSubject = null;
}
// Remove ProductSpecifation. Change ProductSpecifation (realSubject)
// to blanks and change cache state to 'olddeleted' or 'newdeleted'.
public void remove ()
{
ProductSpecification aProductSpec = (ProductSpecification) getRealSubject ();
aProductSpec.setDescription ("");
aProductSpec.setPrice ((float) 0.0);
aProductSpec.setUPC (0);
PFWBroker pfwBroker = (PFWBroker) getBroker ();
pfwBroker.addOldDeletedorNewDeleted (OID, aProductSpec);
}
}
// Filename: ProductSpecificationRelationalBroker.java Author: Anthony F. Ortiz
// This file contains the the RelationalBroker for the
// ProductSpecificationProxy. It's main function is to return the
// ProductSpecification from a ResultSet (which came from a database
// query). It is a singelton.
public class ProductSpecificationRelationalBroker extends RelationalPFWBroker
{
private static ProductSpecificationRelationalBroker instance = new ProductSpecificationRelationalBroker ();
// Private constructor (singelton).
private ProductSpecificationRelationalBroker ()
{
table = "Products";
}
// Get the only instance of ProductSpecificationRelationalBroker
// (singelton).
public static ProductSpecificationRelationalBroker getInstance ()
{
return instance;
}
// Return the current record (ResultSet from a database query).
public Object currentRecordAsObject ()
{
ProductSpecification aProductSpec = new ProductSpecification (Integer.parseInt (currentRecord.field ("upc")), (float) new Double (currentRecord.field ("price")).doubleValue (), currentRecord.field ("description"));
return aProductSpec;
}
// Return a blank record (there was nothing in the ResultSet).
public Object blankRecordAsObject ()
{
ProductSpecification aProductSpec = new ProductSpecification (0, (float) 0.0, "not in db!");
return aProductSpec;
}
// Return a query for inserts and deletes.
public String objectAsRecord (String anOID, Object obj)
{
String query = new String ();
ProductSpecification aProductSpec = (ProductSpecification) obj;
query = "(" + "'" + anOID + "'," + "'" + aProductSpec.getDescription () + "'," + aProductSpec.getPrice () + "," + aProductSpec.getUPC () + ")";
return query;
}
}
// Filename: RandomNumberGenerator.java Author: Anthony F. Ortiz
// This file contains the class which will generate random OID numbers
// for inserts of ProductSpecifications into the database. This class
// makes it less likely, but not impossible for there to be duplicate
// OID numbers in the database (Products table).
public class RandomNumberGenerator
{
// Get a random number from 1 to 1000000.
public static String getRandomNumber ()
{
String str;
int i;
i = (int) (Math.random () * 10000000);
str = "p" + i;
return str;
}
}
// Filename: RDBRecord.java Author: Anthony F. Ortiz
// This file contains the class that holds the ResultSet from a
// database query.
import exgwe.sql.*;
import exjava.sql.*;
public class RDBRecord
{
public ResultSet record = null;
// Get the current record.
public ResultSet getRecord ()
{
return record;
}
// Set the current record.
public void setRecord (ResultSet arecord)
{
record = arecord;
}
// Return the field of a ResultSet which is expressed in the
// the parameter fieldName.
public String field (String fieldName)
{
try
{
return record.getString (fieldName);
}
catch (Exception e)
{
System.out.print (e);
}
return null;
}
}
// Filename: RelationalPFWBroker.java Author: Anthony F. Ortiz
// This file contains the RelationalPFWBroker. It materializes the
// object from the database and returns it (to the proxy).
public abstract class RelationalPFWBroker extends PFWBroker
{
protected RDBRecord currentRecord = new RDBRecord ();
// Materialize an object. Do a select. If the object is in the
// database, add it to the cache and return the object (to the proxy).
// Otherwise, make the object point to a blank record and return it
// (to the proxy).
public Object materializeWith (String anOID)
{
Object obj = new Object ();
obj = selectFirst (anOID);
if (obj != null)
{
obj = currentRecordAsObject ();
addOldClean (anOID, obj);
} // This is for objects that are not in the database.
else
{
obj = blankRecordAsObject ();
}
return obj;
}
// Do a query on the database, set currentRecord to this ResultSet,
// and return the currentRecord.
public Object selectFirst (String anOID)
{
PostDB db = PostDB.getInstance ();
currentRecord.setRecord (db.execute ("select * from " + table + " where OID = " + "'" + anOID + "'"));
return currentRecord.getRecord ();
}
// Abstract method.
public abstract Object currentRecordAsObject ();
// Abstract method.
public abstract String objectAsRecord (String anOID, Object obj);
// Abstract method.
public abstract Object blankRecordAsObject ();
}
// Filename: Sale.java Author: Anthony F. Ortiz
// This file contains one of the 3 realSubjects, Sale. A Sale has a
// lineItems, date, time, and payments as attributes. A Sale's major
// function is to total all its SaleLineItems.
import java.util.*;
public class Sale implements ISale
{
private Vector lineItems = new Vector ();
private String date, time;
private boolean isComplete = false;
private Payment payment;
// Constructor.
public Sale (String adate, String atime)
{
date = adate;
time = atime;
}
// Get balance (customer payment - total of SaleLineItems).
public float getBalance ()
{
return payment.getAmount () - total ();
}
// Get date.
public String getDate ()
{
return date + " " + time;
}
// This is not used in class project.
public void becomeComplete ()
{
isComplete = true;
}
// This is not used in class project.
public boolean isComplete ()
{
return isComplete;
}
// Make another SalelineItem.
public void makeLineItem (String anOID)
{
lineItems.addElement (new SaleLineItemProxy (anOID));
}
// Total all the SaleLineItems.
public float total ()
{
float total = 0;
Enumeration e = lineItems.elements ();
while (e.hasMoreElements ())
{
total += ((SaleLineItemProxy) e.nextElement ()).subtotal ();
}
return total;
}
// set customer's payment.
public void makePayment (float cashTendered)
{
payment = new Payment (cashTendered);
}
}
// Filename: SaleLineItem.java Author: Anthony F. Ortiz
// This file contains one of the 3 realSubjects, SaleLineItem. A
// SaleLineItem has a quantity and a ProductSpecification as
// attributes. It's main function is to get the subtotal of a
// SaleLineItem (quantity * ProductSpecification price).
public class SaleLineItem implements ISaleLineItem
{
private int quantity;
private ProductSpecificationProxy productSpecProxy;
public SaleLineItem (ProductSpecificationProxy specProxy, int quantity)
{
this.productSpecProxy = specProxy;
this.quantity = quantity;
}
public float subtotal ()
{
return quantity * productSpecProxy.getPrice ();
}
}
// Filename: SaleLineItemProxy.java Author: Anthony F. Ortiz
// This file contains the proxy for SaleLineItem.
public class SaleLineItemProxy extends VirtualProxy implements ISaleLineItem
{
// Constructor.
public SaleLineItemProxy (String anOID)
{
OID = anOID;
}
// Get subtotal for a SaleLineItem (realSubject).
public float subtotal ()
{
SaleLineItem aLineItem = (SaleLineItem) getRealSubject ();
return aLineItem.subtotal ();
}
// Create broker for a SaleLineItemProxy.
public Object createBroker ()
{
return SaleLineItemRelationalBroker.getInstance ();
}
// This method is not used for the project.
public void reset ()
{
}
// This method is not used for the project.
public void remove ()
{
}
}
// Filename: SaleLineItemRelationalBroker.java Author: Anthony F. Ortiz
// This file contains the the RelationalBroker for the
// SaleLineItemProxy. It's main function is to return the
// SaleLineItem from a ResultSet (which came from a database
// query). It is a singelton.
public class SaleLineItemRelationalBroker extends RelationalPFWBroker
{
private static SaleLineItemRelationalBroker instance = new SaleLineItemRelationalBroker ();
// Private constructor (singelton).
private SaleLineItemRelationalBroker ()
{
table = "Items";
}
// Get the only instance of SaleLineItemRelationalBroker
// (singelton).
public static SaleLineItemRelationalBroker getInstance ()
{
return instance;
}
// Return the current record (ResultSet from a database query).
public Object currentRecordAsObject ()
{
ProductSpecificationProxy psProxy = new ProductSpecificationProxy (currentRecord.field ("PSOID"));
SaleLineItem aLineItem = new SaleLineItem (psProxy, Integer.parseInt (currentRecord.field ("qty")));
return aLineItem;
}
// Return a blank record (there was nothing in the result set).
public Object blankRecordAsObject ()
{
ProductSpecificationProxy psProxy = new ProductSpecificationProxy ("blank");
SaleLineItem aLineItem = new SaleLineItem (psProxy, 0);
return aLineItem;
}
// This method is not used in the project.
public String objectAsRecord (String anOID, Object obj)
{
String query = new String ();
return query;
}
}
// Filename: SaleProxy.java Author: Anthony F. Ortiz
// This file contains the proxy for Sale.
public class SaleProxy extends VirtualProxy implements ISale
{
// Constructor.
public SaleProxy (String anOID)
{
OID = anOID;
}
// Get balance for a Sale (realSubject).
public float getBalance ()
{
Sale aSale = (Sale) getRealSubject ();
return aSale.getBalance ();
}
// Get the date for a Sale (realSubject).
public String getDate ()
{
Sale aSale = (Sale) getRealSubject ();
return aSale.getDate ();
}
// Get the total for a Sale (realSubject).
public float total ()
{
Sale aSale = (Sale) getRealSubject ();
return aSale.total ();
}
// Create broker for the SaleProxy.
public Object createBroker ()
{
return SaleRelationalBroker.getInstance ();
}
// This method is not used for the project.
public void reset ()
{
}
// This method is not used for the project.
public void remove ()
{
}
}
// Filename: SaleRelationalBroker.java Author: Anthony F. Ortiz
// This file contains the the RelationalBroker for the SaleProxy. It's
// main function is to return the Sale from a ResultSet (which came from
// a database query). It is a singelton.
import java.net.URL.*;
import exjava.math.*;
import exgwe.sql.*;
import exjava.sql.*;
public class SaleRelationalBroker extends RelationalPFWBroker
{
private static SaleRelationalBroker instance = new SaleRelationalBroker ();
// Private constructor (singelton).
private SaleRelationalBroker ()
{
table = "Sales";
}
// Get the only instance of SaleRelationalBroker (singelton).
public static SaleRelationalBroker getInstance ()
{
return instance;
}
// Return the current record (ResultSet from a database query).
public Object currentRecordAsObject ()
{
Sale aSale = new Sale (currentRecord.field ("saledate"), currentRecord.field ("saletime"));
PostDB db = PostDB.getInstance ();
currentRecord.setRecord (db.execute ("select * from " + "SalesItems" + " where SALEOID = " + "'" + currentRecord.field ("OID") + "'"));
try
{
ResultSet rs = currentRecord.getRecord ();
do
{
aSale.makeLineItem (currentRecord.field ("ITEMOID"));
}
while (rs.next ());
}
catch (Exception e)
{
System.out.print (e);
}
return aSale;
}
// Return a blank record (there was nothing in the result set).
public Object blankRecordAsObject ()
{
Sale aSale = new Sale ("not in db!", "not in db!");
return aSale;
}
// This method is not used in the project.
public String objectAsRecord (String anOID, Object obj)
{
String query = new String ();
return query;
}
}
// Filename: VirtualProxy.java Author: Anthony F. Ortiz
// This file contains the VirtualProxy (on-demand materialization) for the
// 3 proxies, ProductSpecificationProxy, SaleLineItemProxy, and SaleProxy.
public abstract class VirtualProxy
{
protected String OID;
protected Object realSubject;
protected Object broker;
// If realSubject is null, materialize realSubject. Otherwise, return
// current realSubject.
public Object getRealSubject ()
{
if (realSubject == null)
{
materializeSubject ();
}
return realSubject;
}
// Materialize realSubject. First get the broker. Then, get the
// realSubject from PFWBroker (either the cache or the database).
public void materializeSubject ()
{
PFWBroker pfwBroker;
pfwBroker = (PFWBroker) getBroker ();
realSubject = pfwBroker.objectWith (OID);
}
// If broker is null, create a broker. Otherwise return the current
// broker.
public Object getBroker ()
{
if (broker == null)
{
broker = createBroker ();
}
return broker;
}
// Abstract method.
public abstract Object createBroker ();
// Abstract method.
public abstract void reset ();
// Abstract method.
public abstract void remove ();
}
// Outfile: Prog1.out
// This program uses a GUI interface.
BACK TO CS6310 PAGE.