diff options
Diffstat (limited to 'examples_java/src/collections/ship/tuple')
13 files changed, 1480 insertions, 0 deletions
diff --git a/examples_java/src/collections/ship/tuple/Part.java b/examples_java/src/collections/ship/tuple/Part.java new file mode 100644 index 0000000..a821e0a --- /dev/null +++ b/examples_java/src/collections/ship/tuple/Part.java @@ -0,0 +1,72 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A Part represents the combined key/data pair for a part entity. + * + * <p> In this sample, Part is created from the stored key/data entry using a + * SerialSerialBinding. See {@link SampleViews.PartBinding} for details. + * Since this class is not directly used for data storage, it does not need to + * be Serializable. </p> + * + * @author Mark Hayes + */ +public class Part { + + private String number; + private String name; + private String color; + private Weight weight; + private String city; + + public Part(String number, String name, String color, Weight weight, + String city) { + + this.number = number; + this.name = name; + this.color = color; + this.weight = weight; + this.city = city; + } + + public final String getNumber() { + + return number; + } + + public final String getName() { + + return name; + } + + public final String getColor() { + + return color; + } + + public final Weight getWeight() { + + return weight; + } + + public final String getCity() { + + return city; + } + + public String toString() { + + return "[Part: number=" + number + + " name=" + name + + " color=" + color + + " weight=" + weight + + " city=" + city + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/PartData.java b/examples_java/src/collections/ship/tuple/PartData.java new file mode 100644 index 0000000..8ccc3b1 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/PartData.java @@ -0,0 +1,65 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.Serializable; + +/** + * A PartData serves as the value in the key/value pair for a part entity. + * + * <p> In this sample, PartData is used only as the storage data for the + * value, while the Part object is used as the value's object representation. + * Because it is used directly as storage data using serial format, it must be + * Serializable. </p> + * + * @author Mark Hayes + */ +public class PartData implements Serializable { + + private String name; + private String color; + private Weight weight; + private String city; + + public PartData(String name, String color, Weight weight, String city) { + + this.name = name; + this.color = color; + this.weight = weight; + this.city = city; + } + + public final String getName() { + + return name; + } + + public final String getColor() { + + return color; + } + + public final Weight getWeight() { + + return weight; + } + + public final String getCity() { + + return city; + } + + public String toString() { + + return "[PartData: name=" + name + + " color=" + color + + " weight=" + weight + + " city=" + city + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/PartKey.java b/examples_java/src/collections/ship/tuple/PartKey.java new file mode 100644 index 0000000..ff65812 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/PartKey.java @@ -0,0 +1,38 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A PartKey serves as the key in the key/data pair for a part entity. + * + * <p> In this sample, PartKey is bound to the key's tuple storage entry using + * a TupleBinding. Because it is not used directly as storage data, it does + * not need to be Serializable. </p> + * + * @author Mark Hayes + */ +public class PartKey { + + private String number; + + public PartKey(String number) { + + this.number = number; + } + + public final String getNumber() { + + return number; + } + + public String toString() { + + return "[PartKey: number=" + number + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/Sample.java b/examples_java/src/collections/ship/tuple/Sample.java new file mode 100644 index 0000000..9c14fc3 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/Sample.java @@ -0,0 +1,235 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.FileNotFoundException; +import java.util.Iterator; +import java.util.Set; + +import com.sleepycat.collections.TransactionRunner; +import com.sleepycat.collections.TransactionWorker; +import com.sleepycat.db.DatabaseException; + +/** + * Sample is the main entry point for the sample program and may be run as + * follows: + * + * <pre> + * java collections.ship.tuple.Sample + * [-h <home-directory> ] + * </pre> + * + * <p> The default for the home directory is ./tmp -- the tmp subdirectory of + * the current directory where the sample is run. The home directory must exist + * before running the sample. To recreate the sample database from scratch, + * delete all files in the home directory before running the sample. </p> + * + * @author Mark Hayes + */ +public class Sample { + + private SampleDatabase db; + private SampleViews views; + + /** + * Run the sample program. + */ + public static void main(String[] args) { + + System.out.println("\nRunning sample: " + Sample.class); + + // Parse the command line arguments. + // + String homeDir = "./tmp"; + for (int i = 0; i < args.length; i += 1) { + if (args[i].equals("-h") && i < args.length - 1) { + i += 1; + homeDir = args[i]; + } else { + System.err.println("Usage:\n java " + Sample.class.getName() + + "\n [-h <home-directory>]"); + System.exit(2); + } + } + + // Run the sample. + // + Sample sample = null; + try { + sample = new Sample(homeDir); + sample.run(); + } catch (Exception e) { + // If an exception reaches this point, the last transaction did not + // complete. If the exception is RunRecoveryException, follow + // the Berkeley DB recovery procedures before running again. + e.printStackTrace(); + } finally { + if (sample != null) { + try { + // Always attempt to close the database cleanly. + sample.close(); + } catch (Exception e) { + System.err.println("Exception during database close:"); + e.printStackTrace(); + } + } + } + } + + /** + * Open the database and views. + */ + private Sample(String homeDir) + throws DatabaseException, FileNotFoundException { + + db = new SampleDatabase(homeDir); + views = new SampleViews(db); + } + + /** + * Close the database cleanly. + */ + private void close() + throws DatabaseException { + + db.close(); + } + + /** + * Run two transactions to populate and print the database. A + * TransactionRunner is used to ensure consistent handling of transactions, + * including deadlock retries. But the best transaction handling mechanism + * to use depends on the application. + */ + private void run() + throws Exception { + + TransactionRunner runner = new TransactionRunner(db.getEnvironment()); + runner.run(new PopulateDatabase()); + runner.run(new PrintDatabase()); + } + + /** + * Populate the database in a single transaction. + */ + private class PopulateDatabase implements TransactionWorker { + + public void doWork() + throws Exception { + addSuppliers(); + addParts(); + addShipments(); + } + } + + /** + * Print the database in a single transaction. All entities are printed + * and the indices are used to print the entities for certain keys. + * + * <p> Note the use of special iterator() methods. These are used here + * with indices to find the shipments for certain keys.</p> + */ + private class PrintDatabase implements TransactionWorker { + + public void doWork() + throws Exception { + printValues("Parts", + views.getPartSet().iterator()); + printValues("Suppliers", + views.getSupplierSet().iterator()); + printValues("Suppliers for City Paris", + views.getSupplierByCityMap().duplicates( + "Paris").iterator()); + printValues("Shipments", + views.getShipmentSet().iterator()); + printValues("Shipments for Part P1", + views.getShipmentByPartMap().duplicates( + new PartKey("P1")).iterator()); + printValues("Shipments for Supplier S1", + views.getShipmentBySupplierMap().duplicates( + new SupplierKey("S1")).iterator()); + } + } + + /** + * Populate the part entities in the database. If the part set is not + * empty, assume that this has already been done. + */ + private void addParts() { + + Set parts = views.getPartSet(); + if (parts.isEmpty()) { + System.out.println("Adding Parts"); + parts.add(new Part("P1", "Nut", "Red", + new Weight(12.0, Weight.GRAMS), "London")); + parts.add(new Part("P2", "Bolt", "Green", + new Weight(17.0, Weight.GRAMS), "Paris")); + parts.add(new Part("P3", "Screw", "Blue", + new Weight(17.0, Weight.GRAMS), "Rome")); + parts.add(new Part("P4", "Screw", "Red", + new Weight(14.0, Weight.GRAMS), "London")); + parts.add(new Part("P5", "Cam", "Blue", + new Weight(12.0, Weight.GRAMS), "Paris")); + parts.add(new Part("P6", "Cog", "Red", + new Weight(19.0, Weight.GRAMS), "London")); + } + } + + /** + * Populate the supplier entities in the database. If the supplier set is + * not empty, assume that this has already been done. + */ + private void addSuppliers() { + + Set suppliers = views.getSupplierSet(); + if (suppliers.isEmpty()) { + System.out.println("Adding Suppliers"); + suppliers.add(new Supplier("S1", "Smith", 20, "London")); + suppliers.add(new Supplier("S2", "Jones", 10, "Paris")); + suppliers.add(new Supplier("S3", "Blake", 30, "Paris")); + suppliers.add(new Supplier("S4", "Clark", 20, "London")); + suppliers.add(new Supplier("S5", "Adams", 30, "Athens")); + } + } + + /** + * Populate the shipment entities in the database. If the shipment set + * is not empty, assume that this has already been done. + */ + private void addShipments() { + + Set shipments = views.getShipmentSet(); + if (shipments.isEmpty()) { + System.out.println("Adding Shipments"); + shipments.add(new Shipment("P1", "S1", 300)); + shipments.add(new Shipment("P2", "S1", 200)); + shipments.add(new Shipment("P3", "S1", 400)); + shipments.add(new Shipment("P4", "S1", 200)); + shipments.add(new Shipment("P5", "S1", 100)); + shipments.add(new Shipment("P6", "S1", 100)); + shipments.add(new Shipment("P1", "S2", 300)); + shipments.add(new Shipment("P2", "S2", 400)); + shipments.add(new Shipment("P2", "S3", 200)); + shipments.add(new Shipment("P2", "S4", 200)); + shipments.add(new Shipment("P4", "S4", 300)); + shipments.add(new Shipment("P5", "S4", 400)); + } + } + + /** + * Print the objects returned by an iterator of entity value objects. + */ + private void printValues(String label, Iterator iterator) { + + System.out.println("\n--- " + label + " ---"); + while (iterator.hasNext()) { + System.out.println(iterator.next().toString()); + } + } +} diff --git a/examples_java/src/collections/ship/tuple/SampleDatabase.java b/examples_java/src/collections/ship/tuple/SampleDatabase.java new file mode 100644 index 0000000..ed42591 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/SampleDatabase.java @@ -0,0 +1,323 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.File; +import java.io.FileNotFoundException; + +import com.sleepycat.bind.serial.ClassCatalog; +import com.sleepycat.bind.serial.StoredClassCatalog; +import com.sleepycat.bind.serial.TupleSerialKeyCreator; +import com.sleepycat.bind.tuple.TupleInput; +import com.sleepycat.bind.tuple.TupleOutput; +import com.sleepycat.db.Database; +import com.sleepycat.db.DatabaseConfig; +import com.sleepycat.db.DatabaseException; +import com.sleepycat.db.DatabaseType; +import com.sleepycat.db.Environment; +import com.sleepycat.db.EnvironmentConfig; +import com.sleepycat.db.ForeignKeyDeleteAction; +import com.sleepycat.db.SecondaryConfig; +import com.sleepycat.db.SecondaryDatabase; + +/** + * SampleDatabase defines the storage containers, indices and foreign keys + * for the sample database. + * + * @author Mark Hayes + */ +public class SampleDatabase { + + private static final String CLASS_CATALOG = "java_class_catalog"; + private static final String SUPPLIER_STORE = "supplier_store"; + private static final String PART_STORE = "part_store"; + private static final String SHIPMENT_STORE = "shipment_store"; + private static final String SHIPMENT_PART_INDEX = "shipment_part_index"; + private static final String SHIPMENT_SUPPLIER_INDEX = + "shipment_supplier_index"; + private static final String SUPPLIER_CITY_INDEX = "supplier_city_index"; + + private Environment env; + private Database partDb; + private Database supplierDb; + private Database shipmentDb; + private SecondaryDatabase supplierByCityDb; + private SecondaryDatabase shipmentByPartDb; + private SecondaryDatabase shipmentBySupplierDb; + private StoredClassCatalog javaCatalog; + + /** + * Open all storage containers, indices, and catalogs. + */ + public SampleDatabase(String homeDirectory) + throws DatabaseException, FileNotFoundException { + + // Open the Berkeley DB environment in transactional mode. + // + System.out.println("Opening environment in: " + homeDirectory); + EnvironmentConfig envConfig = new EnvironmentConfig(); + envConfig.setTransactional(true); + envConfig.setAllowCreate(true); + envConfig.setInitializeCache(true); + envConfig.setInitializeLocking(true); + env = new Environment(new File(homeDirectory), envConfig); + + // Set the Berkeley DB config for opening all stores. + // + DatabaseConfig dbConfig = new DatabaseConfig(); + dbConfig.setTransactional(true); + dbConfig.setAllowCreate(true); + dbConfig.setType(DatabaseType.BTREE); + + // Create the Serial class catalog. This holds the serialized class + // format for all database records of serial format. + // + Database catalogDb = env.openDatabase(null, CLASS_CATALOG, null, + dbConfig); + javaCatalog = new StoredClassCatalog(catalogDb); + + // Open the Berkeley DB database for the part, supplier and shipment + // stores. The stores are opened with no duplicate keys allowed. + // + partDb = env.openDatabase(null, PART_STORE, null, dbConfig); + + supplierDb = env.openDatabase(null, SUPPLIER_STORE, null, dbConfig); + + shipmentDb = env.openDatabase(null, SHIPMENT_STORE, null, dbConfig); + + // Open the SecondaryDatabase for the city index of the supplier store, + // and for the part and supplier indices of the shipment store. + // Duplicate keys are allowed since more than one supplier may be in + // the same city, and more than one shipment may exist for the same + // supplier or part. A foreign key constraint is defined for the + // supplier and part indices to ensure that a shipment only refers to + // existing part and supplier keys. The CASCADE delete action means + // that shipments will be deleted if their associated part or supplier + // is deleted. + // + SecondaryConfig secConfig = new SecondaryConfig(); + secConfig.setTransactional(true); + secConfig.setAllowCreate(true); + secConfig.setType(DatabaseType.BTREE); + secConfig.setSortedDuplicates(true); + + secConfig.setKeyCreator(new SupplierByCityKeyCreator(javaCatalog, + SupplierData.class)); + supplierByCityDb = env.openSecondaryDatabase(null, SUPPLIER_CITY_INDEX, + null, supplierDb, + secConfig); + + secConfig.setForeignKeyDatabase(partDb); + secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE); + secConfig.setKeyCreator(new ShipmentByPartKeyCreator(javaCatalog, + ShipmentData.class)); + shipmentByPartDb = env.openSecondaryDatabase(null, SHIPMENT_PART_INDEX, + null, shipmentDb, + secConfig); + + secConfig.setForeignKeyDatabase(supplierDb); + secConfig.setForeignKeyDeleteAction(ForeignKeyDeleteAction.CASCADE); + secConfig.setKeyCreator(new ShipmentBySupplierKeyCreator(javaCatalog, + ShipmentData.class)); + shipmentBySupplierDb = env.openSecondaryDatabase(null, + SHIPMENT_SUPPLIER_INDEX, + null, shipmentDb, + secConfig); + } + + /** + * Return the storage environment for the database. + */ + public final Environment getEnvironment() { + + return env; + } + + /** + * Return the class catalog. + */ + public final StoredClassCatalog getClassCatalog() { + + return javaCatalog; + } + + /** + * Return the part storage container. + */ + public final Database getPartDatabase() { + + return partDb; + } + + /** + * Return the supplier storage container. + */ + public final Database getSupplierDatabase() { + + return supplierDb; + } + + /** + * Return the shipment storage container. + */ + public final Database getShipmentDatabase() { + + return shipmentDb; + } + + /** + * Return the shipment-by-part index. + */ + public final SecondaryDatabase getShipmentByPartDatabase() { + + return shipmentByPartDb; + } + + /** + * Return the shipment-by-supplier index. + */ + public final SecondaryDatabase getShipmentBySupplierDatabase() { + + return shipmentBySupplierDb; + } + + /** + * Return the supplier-by-city index. + */ + public final SecondaryDatabase getSupplierByCityDatabase() { + + return supplierByCityDb; + } + + /** + * Close all stores (closing a store automatically closes its indices). + */ + public void close() + throws DatabaseException { + + // Close secondary databases, then primary databases. + supplierByCityDb.close(); + shipmentByPartDb.close(); + shipmentBySupplierDb.close(); + partDb.close(); + supplierDb.close(); + shipmentDb.close(); + // And don't forget to close the catalog and the environment. + javaCatalog.close(); + env.close(); + } + + /** + * The SecondaryKeyCreator for the SupplierByCity index. This is an + * extension of the abstract class TupleSerialKeyCreator, which implements + * SecondaryKeyCreator for the case where the data keys are of the format + * TupleFormat and the data values are of the format SerialFormat. + */ + private static class SupplierByCityKeyCreator + extends TupleSerialKeyCreator { + + /** + * Construct the city key extractor. + * @param catalog is the class catalog. + * @param valueClass is the supplier value class. + */ + private SupplierByCityKeyCreator(ClassCatalog catalog, + Class valueClass) { + + super(catalog, valueClass); + } + + /** + * Extract the city key from a supplier key/value pair. The city key + * is stored in the supplier value, so the supplier key is not used. + */ + public boolean createSecondaryKey(TupleInput primaryKeyInput, + Object valueInput, + TupleOutput indexKeyOutput) { + + SupplierData supplierData = (SupplierData) valueInput; + String city = supplierData.getCity(); + if (city != null) { + indexKeyOutput.writeString(supplierData.getCity()); + return true; + } else { + return false; + } + } + } + + /** + * The SecondaryKeyCreator for the ShipmentByPart index. This is an + * extension of the abstract class TupleSerialKeyCreator, which implements + * SecondaryKeyCreator for the case where the data keys are of the format + * TupleFormat and the data values are of the format SerialFormat. + */ + private static class ShipmentByPartKeyCreator + extends TupleSerialKeyCreator { + + /** + * Construct the part key extractor. + * @param catalog is the class catalog. + * @param valueClass is the shipment value class. + */ + private ShipmentByPartKeyCreator(ClassCatalog catalog, + Class valueClass) { + super(catalog, valueClass); + } + + /** + * Extract the part key from a shipment key/value pair. The part key + * is stored in the shipment key, so the shipment value is not used. + */ + public boolean createSecondaryKey(TupleInput primaryKeyInput, + Object valueInput, + TupleOutput indexKeyOutput) { + + String partNumber = primaryKeyInput.readString(); + // don't bother reading the supplierNumber + indexKeyOutput.writeString(partNumber); + return true; + } + } + + /** + * The SecondaryKeyCreator for the ShipmentBySupplier index. This is an + * extension of the abstract class TupleSerialKeyCreator, which implements + * SecondaryKeyCreator for the case where the data keys are of the format + * TupleFormat and the data values are of the format SerialFormat. + */ + private static class ShipmentBySupplierKeyCreator + extends TupleSerialKeyCreator { + + /** + * Construct the supplier key extractor. + * @param catalog is the class catalog. + * @param valueClass is the shipment value class. + */ + private ShipmentBySupplierKeyCreator(ClassCatalog catalog, + Class valueClass) { + super(catalog, valueClass); + } + + /** + * Extract the supplier key from a shipment key/value pair. The + * supplier key is stored in the shipment key, so the shipment value is + * not used. + */ + public boolean createSecondaryKey(TupleInput primaryKeyInput, + Object valueInput, + TupleOutput indexKeyOutput) { + + primaryKeyInput.readString(); // skip the partNumber + String supplierNumber = primaryKeyInput.readString(); + indexKeyOutput.writeString(supplierNumber); + return true; + } + } +} diff --git a/examples_java/src/collections/ship/tuple/SampleViews.java b/examples_java/src/collections/ship/tuple/SampleViews.java new file mode 100644 index 0000000..3bb4b1d --- /dev/null +++ b/examples_java/src/collections/ship/tuple/SampleViews.java @@ -0,0 +1,396 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import com.sleepycat.bind.EntityBinding; +import com.sleepycat.bind.EntryBinding; +import com.sleepycat.bind.serial.ClassCatalog; +import com.sleepycat.bind.serial.TupleSerialBinding; +import com.sleepycat.bind.tuple.TupleBinding; +import com.sleepycat.bind.tuple.TupleInput; +import com.sleepycat.bind.tuple.TupleOutput; +import com.sleepycat.collections.StoredSortedMap; +import com.sleepycat.collections.StoredSortedValueSet; + +/** + * SampleViews defines the data bindings and collection views for the sample + * database. + * + * @author Mark Hayes + */ +public class SampleViews { + + private StoredSortedMap partMap; + private StoredSortedMap supplierMap; + private StoredSortedMap shipmentMap; + private StoredSortedMap shipmentByPartMap; + private StoredSortedMap shipmentBySupplierMap; + private StoredSortedMap supplierByCityMap; + + /** + * Create the data bindings and collection views. + */ + public SampleViews(SampleDatabase db) { + + // Create the data bindings. + // In this sample, EntityBinding classes are used to bind the stored + // key/data entry pair to a combined data object. For keys, a + // one-to-one binding is implemented with EntryBinding classes to bind + // the stored tuple entry to a key Object. + // + ClassCatalog catalog = db.getClassCatalog(); + EntryBinding partKeyBinding = + new PartKeyBinding(); + EntityBinding partDataBinding = + new PartBinding(catalog, PartData.class); + EntryBinding supplierKeyBinding = + new SupplierKeyBinding(); + EntityBinding supplierDataBinding = + new SupplierBinding(catalog, SupplierData.class); + EntryBinding shipmentKeyBinding = + new ShipmentKeyBinding(); + EntityBinding shipmentDataBinding = + new ShipmentBinding(catalog, ShipmentData.class); + EntryBinding cityKeyBinding = + TupleBinding.getPrimitiveBinding(String.class); + + // Create map views for all stores and indices. + // StoredSortedMap is used since the stores and indices are ordered + // (they use the DB_BTREE access method). + // + partMap = + new StoredSortedMap(db.getPartDatabase(), + partKeyBinding, partDataBinding, true); + supplierMap = + new StoredSortedMap(db.getSupplierDatabase(), + supplierKeyBinding, supplierDataBinding, true); + shipmentMap = + new StoredSortedMap(db.getShipmentDatabase(), + shipmentKeyBinding, shipmentDataBinding, true); + shipmentByPartMap = + new StoredSortedMap(db.getShipmentByPartDatabase(), + partKeyBinding, shipmentDataBinding, true); + shipmentBySupplierMap = + new StoredSortedMap(db.getShipmentBySupplierDatabase(), + supplierKeyBinding, shipmentDataBinding, true); + supplierByCityMap = + new StoredSortedMap(db.getSupplierByCityDatabase(), + cityKeyBinding, supplierDataBinding, true); + } + + // The views returned below can be accessed using the java.util.Map or + // java.util.Set interfaces, or using the StoredSortedMap and + // StoredValueSet classes, which provide additional methods. The entity + // sets could be obtained directly from the Map.values() method but + // convenience methods are provided here to return them in order to avoid + // down-casting elsewhere. + + /** + * Return a map view of the part storage container. + */ + public StoredSortedMap getPartMap() { + + return partMap; + } + + /** + * Return a map view of the supplier storage container. + */ + public StoredSortedMap getSupplierMap() { + + return supplierMap; + } + + /** + * Return a map view of the shipment storage container. + */ + public StoredSortedMap getShipmentMap() { + + return shipmentMap; + } + + /** + * Return an entity set view of the part storage container. + */ + public StoredSortedValueSet getPartSet() { + + return (StoredSortedValueSet) partMap.values(); + } + + /** + * Return an entity set view of the supplier storage container. + */ + public StoredSortedValueSet getSupplierSet() { + + return (StoredSortedValueSet) supplierMap.values(); + } + + /** + * Return an entity set view of the shipment storage container. + */ + public StoredSortedValueSet getShipmentSet() { + + return (StoredSortedValueSet) shipmentMap.values(); + } + + /** + * Return a map view of the shipment-by-part index. + */ + public StoredSortedMap getShipmentByPartMap() { + + return shipmentByPartMap; + } + + /** + * Return a map view of the shipment-by-supplier index. + */ + public StoredSortedMap getShipmentBySupplierMap() { + + return shipmentBySupplierMap; + } + + /** + * Return a map view of the supplier-by-city index. + */ + public final StoredSortedMap getSupplierByCityMap() { + + return supplierByCityMap; + } + + /** + * PartKeyBinding is used to bind the stored key tuple entry for a part to + * a key object representation. + */ + private static class PartKeyBinding extends TupleBinding { + + /** + * Construct the binding object. + */ + private PartKeyBinding() { + } + + /** + * Create the key object from the stored key tuple entry. + */ + public Object entryToObject(TupleInput input) { + + String number = input.readString(); + return new PartKey(number); + } + + /** + * Create the stored key tuple entry from the key object. + */ + public void objectToEntry(Object object, TupleOutput output) { + + PartKey key = (PartKey) object; + output.writeString(key.getNumber()); + } + } + + /** + * PartBinding is used to bind the stored key/data entry pair for a part + * to a combined data object (entity). + */ + private static class PartBinding extends TupleSerialBinding { + + /** + * Construct the binding object. + */ + private PartBinding(ClassCatalog classCatalog, Class dataClass) { + + super(classCatalog, dataClass); + } + + /** + * Create the entity by combining the stored key and data. + */ + public Object entryToObject(TupleInput keyInput, Object dataInput) { + + String number = keyInput.readString(); + PartData data = (PartData) dataInput; + return new Part(number, data.getName(), data.getColor(), + data.getWeight(), data.getCity()); + } + + /** + * Create the stored key from the entity. + */ + public void objectToKey(Object object, TupleOutput output) { + + Part part = (Part) object; + output.writeString(part.getNumber()); + } + + /** + * Create the stored data from the entity. + */ + public Object objectToData(Object object) { + + Part part = (Part) object; + return new PartData(part.getName(), part.getColor(), + part.getWeight(), part.getCity()); + } + } + + /** + * SupplierKeyBinding is used to bind the stored key tuple entry for a + * supplier to a key object representation. + */ + private static class SupplierKeyBinding extends TupleBinding { + + /** + * Construct the binding object. + */ + private SupplierKeyBinding() { + } + + /** + * Create the key object from the stored key tuple entry. + */ + public Object entryToObject(TupleInput input) { + + String number = input.readString(); + return new SupplierKey(number); + } + + /** + * Create the stored key tuple entry from the key object. + */ + public void objectToEntry(Object object, TupleOutput output) { + + SupplierKey key = (SupplierKey) object; + output.writeString(key.getNumber()); + } + } + + /** + * SupplierBinding is used to bind the stored key/data entry pair for a + * supplier to a combined data object (entity). + */ + private static class SupplierBinding extends TupleSerialBinding { + + /** + * Construct the binding object. + */ + private SupplierBinding(ClassCatalog classCatalog, Class dataClass) { + + super(classCatalog, dataClass); + } + + /** + * Create the entity by combining the stored key and data. + */ + public Object entryToObject(TupleInput keyInput, Object dataInput) { + + String number = keyInput.readString(); + SupplierData data = (SupplierData) dataInput; + return new Supplier(number, data.getName(), + data.getStatus(), data.getCity()); + } + + /** + * Create the stored key from the entity. + */ + public void objectToKey(Object object, TupleOutput output) { + + Supplier supplier = (Supplier) object; + output.writeString(supplier.getNumber()); + } + + /** + * Create the stored data from the entity. + */ + public Object objectToData(Object object) { + + Supplier supplier = (Supplier) object; + return new SupplierData(supplier.getName(), supplier.getStatus(), + supplier.getCity()); + } + } + + /** + * ShipmentKeyBinding is used to bind the stored key tuple entry for a + * shipment to a key object representation. + */ + private static class ShipmentKeyBinding extends TupleBinding { + + /** + * Construct the binding object. + */ + private ShipmentKeyBinding() { + } + + /** + * Create the key object from the stored key tuple entry. + */ + public Object entryToObject(TupleInput input) { + + String partNumber = input.readString(); + String supplierNumber = input.readString(); + return new ShipmentKey(partNumber, supplierNumber); + } + + /** + * Create the stored key tuple entry from the key object. + */ + public void objectToEntry(Object object, TupleOutput output) { + + ShipmentKey key = (ShipmentKey) object; + output.writeString(key.getPartNumber()); + output.writeString(key.getSupplierNumber()); + } + } + + /** + * ShipmentBinding is used to bind the stored key/data entry pair for a + * shipment to a combined data object (entity). + */ + private static class ShipmentBinding extends TupleSerialBinding { + + /** + * Construct the binding object. + */ + private ShipmentBinding(ClassCatalog classCatalog, Class dataClass) { + + super(classCatalog, dataClass); + } + + /** + * Create the entity by combining the stored key and data. + */ + public Object entryToObject(TupleInput keyInput, Object dataInput) { + + String partNumber = keyInput.readString(); + String supplierNumber = keyInput.readString(); + ShipmentData data = (ShipmentData) dataInput; + return new Shipment(partNumber, supplierNumber, + data.getQuantity()); + } + + /** + * Create the stored key from the entity. + */ + public void objectToKey(Object object, TupleOutput output) { + + Shipment shipment = (Shipment) object; + output.writeString(shipment.getPartNumber()); + output.writeString(shipment.getSupplierNumber()); + } + + /** + * Create the stored data from the entity. + */ + public Object objectToData(Object object) { + + Shipment shipment = (Shipment) object; + return new ShipmentData(shipment.getQuantity()); + } + } +} diff --git a/examples_java/src/collections/ship/tuple/Shipment.java b/examples_java/src/collections/ship/tuple/Shipment.java new file mode 100644 index 0000000..6c15ea0 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/Shipment.java @@ -0,0 +1,55 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A Shipment represents the combined key/data pair for a shipment entity. + * + * <p> In this sample, Shipment is created from the stored key/data entry + * using a SerialSerialBinding. See {@link SampleViews.ShipmentBinding} for + * details. Since this class is not used directly for data storage, it does + * not need to be Serializable. </p> + * + * @author Mark Hayes + */ +public class Shipment { + + private String partNumber; + private String supplierNumber; + private int quantity; + + public Shipment(String partNumber, String supplierNumber, int quantity) { + + this.partNumber = partNumber; + this.supplierNumber = supplierNumber; + this.quantity = quantity; + } + + public final String getPartNumber() { + + return partNumber; + } + + public final String getSupplierNumber() { + + return supplierNumber; + } + + public final int getQuantity() { + + return quantity; + } + + public String toString() { + + return "[Shipment: part=" + partNumber + + " supplier=" + supplierNumber + + " quantity=" + quantity + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/ShipmentData.java b/examples_java/src/collections/ship/tuple/ShipmentData.java new file mode 100644 index 0000000..4009c61 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/ShipmentData.java @@ -0,0 +1,42 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.Serializable; + +/** + * A ShipmentData serves as the value in the key/value pair for a shipment + * entity. + * + * <p> In this sample, ShipmentData is used only as the storage data for the + * value, while the Shipment object is used as the value's object + * representation. Because it is used directly as storage data using + * serial format, it must be Serializable. </p> + * + * @author Mark Hayes + */ +public class ShipmentData implements Serializable { + + private int quantity; + + public ShipmentData(int quantity) { + + this.quantity = quantity; + } + + public final int getQuantity() { + + return quantity; + } + + public String toString() { + + return "[ShipmentData: quantity=" + quantity + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/ShipmentKey.java b/examples_java/src/collections/ship/tuple/ShipmentKey.java new file mode 100644 index 0000000..83d4a18 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/ShipmentKey.java @@ -0,0 +1,46 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A ShipmentKey serves as the key in the key/data pair for a shipment entity. + * + * <p> In this sample, ShipmentKey is bound to the key's tuple storage entry + * using a TupleBinding. Because it is not used directly as storage data, it + * does not need to be Serializable. </p> + * + * @author Mark Hayes + */ +public class ShipmentKey { + + private String partNumber; + private String supplierNumber; + + public ShipmentKey(String partNumber, String supplierNumber) { + + this.partNumber = partNumber; + this.supplierNumber = supplierNumber; + } + + public final String getPartNumber() { + + return partNumber; + } + + public final String getSupplierNumber() { + + return supplierNumber; + } + + public String toString() { + + return "[ShipmentKey: supplier=" + supplierNumber + + " part=" + partNumber + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/Supplier.java b/examples_java/src/collections/ship/tuple/Supplier.java new file mode 100644 index 0000000..8466271 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/Supplier.java @@ -0,0 +1,63 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A Supplier represents the combined key/data pair for a supplier entity. + * + * <p> In this sample, Supplier is created from the stored key/data entry + * using a SerialSerialBinding. See {@link SampleViews.SupplierBinding} for + * details. Since this class is not used directly for data storage, it does + * not need to be Serializable. </p> + * + * @author Mark Hayes + */ +public class Supplier { + + private String number; + private String name; + private int status; + private String city; + + public Supplier(String number, String name, int status, String city) { + + this.number = number; + this.name = name; + this.status = status; + this.city = city; + } + + public final String getNumber() { + + return number; + } + + public final String getName() { + + return name; + } + + public final int getStatus() { + + return status; + } + + public final String getCity() { + + return city; + } + + public String toString() { + + return "[Supplier: number=" + number + + " name=" + name + + " status=" + status + + " city=" + city + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/SupplierData.java b/examples_java/src/collections/ship/tuple/SupplierData.java new file mode 100644 index 0000000..6e863b9 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/SupplierData.java @@ -0,0 +1,58 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.Serializable; + +/** + * A SupplierData serves as the value in the key/value pair for a supplier + * entity. + * + * <p> In this sample, SupplierData is used only as the storage data for the + * value, while the Supplier object is used as the value's object + * representation. Because it is used directly as storage data using + * serial format, it must be Serializable. </p> + * + * @author Mark Hayes + */ +public class SupplierData implements Serializable { + + private String name; + private int status; + private String city; + + public SupplierData(String name, int status, String city) { + + this.name = name; + this.status = status; + this.city = city; + } + + public final String getName() { + + return name; + } + + public final int getStatus() { + + return status; + } + + public final String getCity() { + + return city; + } + + public String toString() { + + return "[SupplierData: name=" + name + + " status=" + status + + " city=" + city + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/SupplierKey.java b/examples_java/src/collections/ship/tuple/SupplierKey.java new file mode 100644 index 0000000..afc1fa0 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/SupplierKey.java @@ -0,0 +1,38 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +/** + * A SupplierKey serves as the key in the key/data pair for a supplier entity. + * + * <p> In this sample, SupplierKey is bound to the key's tuple storage entry + * using a TupleBinding. Because it is not used directly as storage data, it + * does not need to be Serializable. </p> + * + * @author Mark Hayes + */ +public class SupplierKey { + + private String number; + + public SupplierKey(String number) { + + this.number = number; + } + + public final String getNumber() { + + return number; + } + + public String toString() { + + return "[SupplierKey: number=" + number + ']'; + } +} diff --git a/examples_java/src/collections/ship/tuple/Weight.java b/examples_java/src/collections/ship/tuple/Weight.java new file mode 100644 index 0000000..850e5c4 --- /dev/null +++ b/examples_java/src/collections/ship/tuple/Weight.java @@ -0,0 +1,49 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2002-2009 Oracle. All rights reserved. + * + * $Id$ + */ + +package collections.ship.tuple; + +import java.io.Serializable; + +/** + * Weight represents a weight amount and unit of measure. + * + * <p> In this sample, Weight is embedded in part data values which are stored + * as Java serialized objects; therefore Weight must be Serializable. </p> + * + * @author Mark Hayes + */ +public class Weight implements Serializable { + + public final static String GRAMS = "grams"; + public final static String OUNCES = "ounces"; + + private double amount; + private String units; + + public Weight(double amount, String units) { + + this.amount = amount; + this.units = units; + } + + public final double getAmount() { + + return amount; + } + + public final String getUnits() { + + return units; + } + + public String toString() { + + return "[" + amount + ' ' + units + ']'; + } +} |