1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: SampleViews.java,v 12.7 2008/01/08 20:58:31 bostic Exp $ 7 */ 8 9package collections.ship.sentity; 10 11import com.sleepycat.bind.EntityBinding; 12import com.sleepycat.bind.EntryBinding; 13import com.sleepycat.bind.serial.ClassCatalog; 14import com.sleepycat.bind.serial.TupleSerialBinding; 15import com.sleepycat.bind.tuple.TupleBinding; 16import com.sleepycat.bind.tuple.TupleInput; 17import com.sleepycat.bind.tuple.TupleOutput; 18import com.sleepycat.collections.StoredSortedMap; 19import com.sleepycat.collections.StoredSortedValueSet; 20 21/** 22 * SampleViews defines the data bindings and collection views for the sample 23 * database. 24 * 25 * @author Mark Hayes 26 */ 27public class SampleViews { 28 29 private StoredSortedMap partMap; 30 private StoredSortedMap supplierMap; 31 private StoredSortedMap shipmentMap; 32 private StoredSortedMap shipmentByPartMap; 33 private StoredSortedMap shipmentBySupplierMap; 34 private StoredSortedMap supplierByCityMap; 35 36 /** 37 * Create the data bindings and collection views. 38 */ 39 public SampleViews(SampleDatabase db) { 40 41 // Create the data bindings. 42 // In this sample, EntityBinding classes are used to bind the stored 43 // key/data entry pair to a combined data object; a "tricky" binding 44 // that uses transient fields is used--see PartBinding, etc, for 45 // details. For keys, a one-to-one binding is implemented with 46 // EntryBinding classes to bind the stored tuple entry to a key Object. 47 // 48 ClassCatalog catalog = db.getClassCatalog(); 49 EntryBinding partKeyBinding = 50 new PartKeyBinding(); 51 EntityBinding partDataBinding = 52 new PartBinding(catalog, Part.class); 53 EntryBinding supplierKeyBinding = 54 new SupplierKeyBinding(); 55 EntityBinding supplierDataBinding = 56 new SupplierBinding(catalog, Supplier.class); 57 EntryBinding shipmentKeyBinding = 58 new ShipmentKeyBinding(); 59 EntityBinding shipmentDataBinding = 60 new ShipmentBinding(catalog, Shipment.class); 61 EntryBinding cityKeyBinding = 62 TupleBinding.getPrimitiveBinding(String.class); 63 64 // Create map views for all stores and indices. 65 // StoredSortedMap is used since the stores and indices are ordered 66 // (they use the DB_BTREE access method). 67 // 68 partMap = 69 new StoredSortedMap(db.getPartDatabase(), 70 partKeyBinding, partDataBinding, true); 71 supplierMap = 72 new StoredSortedMap(db.getSupplierDatabase(), 73 supplierKeyBinding, supplierDataBinding, true); 74 shipmentMap = 75 new StoredSortedMap(db.getShipmentDatabase(), 76 shipmentKeyBinding, shipmentDataBinding, true); 77 shipmentByPartMap = 78 new StoredSortedMap(db.getShipmentByPartDatabase(), 79 partKeyBinding, shipmentDataBinding, true); 80 shipmentBySupplierMap = 81 new StoredSortedMap(db.getShipmentBySupplierDatabase(), 82 supplierKeyBinding, shipmentDataBinding, true); 83 supplierByCityMap = 84 new StoredSortedMap(db.getSupplierByCityDatabase(), 85 cityKeyBinding, supplierDataBinding, true); 86 } 87 88 // The views returned below can be accessed using the java.util.Map or 89 // java.util.Set interfaces, or using the StoredSortedMap and 90 // StoredValueSet classes, which provide additional methods. The entity 91 // sets could be obtained directly from the Map.values() method but 92 // convenience methods are provided here to return them in order to avoid 93 // down-casting elsewhere. 94 95 /** 96 * Return a map view of the part storage container. 97 */ 98 public StoredSortedMap getPartMap() { 99 100 return partMap; 101 } 102 103 /** 104 * Return a map view of the supplier storage container. 105 */ 106 public StoredSortedMap getSupplierMap() { 107 108 return supplierMap; 109 } 110 111 /** 112 * Return a map view of the shipment storage container. 113 */ 114 public StoredSortedMap getShipmentMap() { 115 116 return shipmentMap; 117 } 118 119 /** 120 * Return an entity set view of the part storage container. 121 */ 122 public StoredSortedValueSet getPartSet() { 123 124 return (StoredSortedValueSet) partMap.values(); 125 } 126 127 /** 128 * Return an entity set view of the supplier storage container. 129 */ 130 public StoredSortedValueSet getSupplierSet() { 131 132 return (StoredSortedValueSet) supplierMap.values(); 133 } 134 135 /** 136 * Return an entity set view of the shipment storage container. 137 */ 138 public StoredSortedValueSet getShipmentSet() { 139 140 return (StoredSortedValueSet) shipmentMap.values(); 141 } 142 143 /** 144 * Return a map view of the shipment-by-part index. 145 */ 146 public StoredSortedMap getShipmentByPartMap() { 147 148 return shipmentByPartMap; 149 } 150 151 /** 152 * Return a map view of the shipment-by-supplier index. 153 */ 154 public StoredSortedMap getShipmentBySupplierMap() { 155 156 return shipmentBySupplierMap; 157 } 158 159 /** 160 * Return a map view of the supplier-by-city index. 161 */ 162 public final StoredSortedMap getSupplierByCityMap() { 163 164 return supplierByCityMap; 165 } 166 167 /** 168 * PartKeyBinding is used to bind the stored key tuple entry for a part to 169 * a key object representation. 170 */ 171 private static class PartKeyBinding extends TupleBinding { 172 173 /** 174 * Construct the binding object. 175 */ 176 private PartKeyBinding() { 177 } 178 179 /** 180 * Create the key object from the stored key tuple entry. 181 */ 182 public Object entryToObject(TupleInput input) { 183 184 String number = input.readString(); 185 return new PartKey(number); 186 } 187 188 /** 189 * Create the stored key tuple entry from the key object. 190 */ 191 public void objectToEntry(Object object, TupleOutput output) { 192 193 PartKey key = (PartKey) object; 194 output.writeString(key.getNumber()); 195 } 196 } 197 198 /** 199 * PartBinding is used to bind the stored key/data entry pair for a part 200 * to a combined data object (entity). 201 * 202 * <p> The binding is "tricky" in that it uses the Part class for both the 203 * stored data entry and the combined entity object. To do this, Part's 204 * key field(s) are transient and are set by the binding after the data 205 * object has been deserialized. This avoids the use of a PartData class 206 * completely. </p> 207 */ 208 private static class PartBinding extends TupleSerialBinding { 209 210 /** 211 * Construct the binding object. 212 */ 213 private PartBinding(ClassCatalog classCatalog, Class dataClass) { 214 215 super(classCatalog, dataClass); 216 } 217 218 /** 219 * Create the entity by combining the stored key and data. 220 * This "tricky" binding returns the stored data as the entity, but 221 * first it sets the transient key fields from the stored key. 222 */ 223 public Object entryToObject(TupleInput keyInput, Object dataInput) { 224 225 String number = keyInput.readString(); 226 Part part = (Part) dataInput; 227 part.setKey(number); 228 return part; 229 } 230 231 /** 232 * Create the stored key from the entity. 233 */ 234 public void objectToKey(Object object, TupleOutput output) { 235 236 Part part = (Part) object; 237 output.writeString(part.getNumber()); 238 } 239 240 /** 241 * Return the entity as the stored data. There is nothing to do here 242 * since the entity's key fields are transient. 243 */ 244 public Object objectToData(Object object) { 245 246 return object; 247 } 248 } 249 250 /** 251 * SupplierKeyBinding is used to bind the stored key tuple entry for a 252 * supplier to a key object representation. 253 */ 254 private static class SupplierKeyBinding extends TupleBinding { 255 256 /** 257 * Construct the binding object. 258 */ 259 private SupplierKeyBinding() { 260 } 261 262 /** 263 * Create the key object from the stored key tuple entry. 264 */ 265 public Object entryToObject(TupleInput input) { 266 267 String number = input.readString(); 268 return new SupplierKey(number); 269 } 270 271 /** 272 * Create the stored key tuple entry from the key object. 273 */ 274 public void objectToEntry(Object object, TupleOutput output) { 275 276 SupplierKey key = (SupplierKey) object; 277 output.writeString(key.getNumber()); 278 } 279 } 280 281 /** 282 * SupplierBinding is used to bind the stored key/data entry pair for a 283 * supplier to a combined data object (entity). 284 * 285 * <p> The binding is "tricky" in that it uses the Supplier class for both 286 * the stored data entry and the combined entity object. To do this, 287 * Supplier's key field(s) are transient and are set by the binding after 288 * the data object has been deserialized. This avoids the use of a 289 * SupplierData class completely. </p> 290 */ 291 private static class SupplierBinding extends TupleSerialBinding { 292 293 /** 294 * Construct the binding object. 295 */ 296 private SupplierBinding(ClassCatalog classCatalog, Class dataClass) { 297 298 super(classCatalog, dataClass); 299 } 300 301 /** 302 * Create the entity by combining the stored key and data. 303 * This "tricky" binding returns the stored data as the entity, but 304 * first it sets the transient key fields from the stored key. 305 */ 306 public Object entryToObject(TupleInput keyInput, Object dataInput) { 307 308 String number = keyInput.readString(); 309 Supplier supplier = (Supplier) dataInput; 310 supplier.setKey(number); 311 return supplier; 312 } 313 314 /** 315 * Create the stored key from the entity. 316 */ 317 public void objectToKey(Object object, TupleOutput output) { 318 319 Supplier supplier = (Supplier) object; 320 output.writeString(supplier.getNumber()); 321 } 322 323 /** 324 * Return the entity as the stored data. There is nothing to do here 325 * since the entity's key fields are transient. 326 */ 327 public Object objectToData(Object object) { 328 329 return object; 330 } 331 } 332 333 /** 334 * ShipmentKeyBinding is used to bind the stored key tuple entry for a 335 * shipment to a key object representation. 336 */ 337 private static class ShipmentKeyBinding extends TupleBinding { 338 339 /** 340 * Construct the binding object. 341 */ 342 private ShipmentKeyBinding() { 343 } 344 345 /** 346 * Create the key object from the stored key tuple entry. 347 */ 348 public Object entryToObject(TupleInput input) { 349 350 String partNumber = input.readString(); 351 String supplierNumber = input.readString(); 352 return new ShipmentKey(partNumber, supplierNumber); 353 } 354 355 /** 356 * Create the stored key tuple entry from the key object. 357 */ 358 public void objectToEntry(Object object, TupleOutput output) { 359 360 ShipmentKey key = (ShipmentKey) object; 361 output.writeString(key.getPartNumber()); 362 output.writeString(key.getSupplierNumber()); 363 } 364 } 365 366 /** 367 * ShipmentBinding is used to bind the stored key/data entry pair for a 368 * shipment to a combined data object (entity). 369 * 370 * <p> The binding is "tricky" in that it uses the Shipment class for both 371 * the stored data entry and the combined entity object. To do this, 372 * Shipment's key field(s) are transient and are set by the binding after 373 * the data object has been deserialized. This avoids the use of a 374 * ShipmentData class completely. </p> 375 */ 376 private static class ShipmentBinding extends TupleSerialBinding { 377 378 /** 379 * Construct the binding object. 380 */ 381 private ShipmentBinding(ClassCatalog classCatalog, Class dataClass) { 382 383 super(classCatalog, dataClass); 384 } 385 386 /** 387 * Create the entity by combining the stored key and data. 388 * This "tricky" binding returns the stored data as the entity, but 389 * first it sets the transient key fields from the stored key. 390 */ 391 public Object entryToObject(TupleInput keyInput, Object dataInput) { 392 393 String partNumber = keyInput.readString(); 394 String supplierNumber = keyInput.readString(); 395 Shipment shipment = (Shipment) dataInput; 396 shipment.setKey(partNumber, supplierNumber); 397 return shipment; 398 } 399 400 /** 401 * Create the stored key from the entity. 402 */ 403 public void objectToKey(Object object, TupleOutput output) { 404 405 Shipment shipment = (Shipment) object; 406 output.writeString(shipment.getPartNumber()); 407 output.writeString(shipment.getSupplierNumber()); 408 } 409 410 /** 411 * Return the entity as the stored data. There is nothing to do here 412 * since the entity's key fields are transient. 413 */ 414 public Object objectToData(Object object) { 415 416 return object; 417 } 418 } 419} 420