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.