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:30 bostic Exp $ 7 */ 8 9package collections.ship.marshal; 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; 20import com.sleepycat.util.RuntimeExceptionWrapper; 21 22/** 23 * SampleViews defines the data bindings and collection views for the sample 24 * database. 25 * 26 * @author Mark Hayes 27 */ 28public class SampleViews { 29 30 private StoredSortedMap partMap; 31 private StoredSortedMap supplierMap; 32 private StoredSortedMap shipmentMap; 33 private StoredSortedMap shipmentByPartMap; 34 private StoredSortedMap shipmentBySupplierMap; 35 private StoredSortedMap supplierByCityMap; 36 37 /** 38 * Create the data bindings and collection views. 39 */ 40 public SampleViews(SampleDatabase db) { 41 42 // Create the data bindings. 43 // In this sample, EntityBinding classes are used to bind the stored 44 // key/data entry pair to a combined data object; a "tricky" binding 45 // that uses transient fields is used--see PartBinding, etc, for 46 // details. For keys, a one-to-one binding is implemented with 47 // EntryBinding classes to bind the stored tuple entry to a key Object. 48 // 49 ClassCatalog catalog = db.getClassCatalog(); 50 EntryBinding partKeyBinding = 51 new MarshalledKeyBinding(PartKey.class); 52 EntityBinding partDataBinding = 53 new MarshalledEntityBinding(catalog, Part.class); 54 EntryBinding supplierKeyBinding = 55 new MarshalledKeyBinding(SupplierKey.class); 56 EntityBinding supplierDataBinding = 57 new MarshalledEntityBinding(catalog, Supplier.class); 58 EntryBinding shipmentKeyBinding = 59 new MarshalledKeyBinding(ShipmentKey.class); 60 EntityBinding shipmentDataBinding = 61 new MarshalledEntityBinding(catalog, Shipment.class); 62 EntryBinding cityKeyBinding = 63 TupleBinding.getPrimitiveBinding(String.class); 64 65 // Create map views for all stores and indices. 66 // StoredSortedMap is used since the stores and indices are ordered 67 // (they use the DB_BTREE access method). 68 // 69 partMap = 70 new StoredSortedMap(db.getPartDatabase(), 71 partKeyBinding, partDataBinding, true); 72 supplierMap = 73 new StoredSortedMap(db.getSupplierDatabase(), 74 supplierKeyBinding, supplierDataBinding, true); 75 shipmentMap = 76 new StoredSortedMap(db.getShipmentDatabase(), 77 shipmentKeyBinding, shipmentDataBinding, true); 78 shipmentByPartMap = 79 new StoredSortedMap(db.getShipmentByPartDatabase(), 80 partKeyBinding, shipmentDataBinding, true); 81 shipmentBySupplierMap = 82 new StoredSortedMap(db.getShipmentBySupplierDatabase(), 83 supplierKeyBinding, shipmentDataBinding, true); 84 supplierByCityMap = 85 new StoredSortedMap(db.getSupplierByCityDatabase(), 86 cityKeyBinding, supplierDataBinding, true); 87 } 88 89 // The views returned below can be accessed using the java.util.Map or 90 // java.util.Set interfaces, or using the StoredSortedMap and 91 // StoredValueSet classes, which provide additional methods. The entity 92 // sets could be obtained directly from the Map.values() method but 93 // convenience methods are provided here to return them in order to avoid 94 // down-casting elsewhere. 95 96 /** 97 * Return a map view of the part storage container. 98 */ 99 public StoredSortedMap getPartMap() { 100 101 return partMap; 102 } 103 104 /** 105 * Return a map view of the supplier storage container. 106 */ 107 public StoredSortedMap getSupplierMap() { 108 109 return supplierMap; 110 } 111 112 /** 113 * Return a map view of the shipment storage container. 114 */ 115 public StoredSortedMap getShipmentMap() { 116 117 return shipmentMap; 118 } 119 120 /** 121 * Return an entity set view of the part storage container. 122 */ 123 public StoredSortedValueSet getPartSet() { 124 125 return (StoredSortedValueSet) partMap.values(); 126 } 127 128 /** 129 * Return an entity set view of the supplier storage container. 130 */ 131 public StoredSortedValueSet getSupplierSet() { 132 133 return (StoredSortedValueSet) supplierMap.values(); 134 } 135 136 /** 137 * Return an entity set view of the shipment storage container. 138 */ 139 public StoredSortedValueSet getShipmentSet() { 140 141 return (StoredSortedValueSet) shipmentMap.values(); 142 } 143 144 /** 145 * Return a map view of the shipment-by-part index. 146 */ 147 public StoredSortedMap getShipmentByPartMap() { 148 149 return shipmentByPartMap; 150 } 151 152 /** 153 * Return a map view of the shipment-by-supplier index. 154 */ 155 public StoredSortedMap getShipmentBySupplierMap() { 156 157 return shipmentBySupplierMap; 158 } 159 160 /** 161 * Return a map view of the supplier-by-city index. 162 */ 163 public final StoredSortedMap getSupplierByCityMap() { 164 165 return supplierByCityMap; 166 } 167 168 /** 169 * MarshalledKeyBinding is used to bind the stored key tuple entry to a key 170 * object representation. To do this, it calls the MarshalledKey interface 171 * implemented by the key class. 172 */ 173 private static class MarshalledKeyBinding extends TupleBinding { 174 175 private Class keyClass; 176 177 /** 178 * Construct the binding object. 179 */ 180 private MarshalledKeyBinding(Class keyClass) { 181 182 // The key class will be used to instantiate the key object. 183 // 184 if (!MarshalledKey.class.isAssignableFrom(keyClass)) { 185 throw new IllegalArgumentException(keyClass.toString() + 186 " does not implement MarshalledKey"); 187 } 188 this.keyClass = keyClass; 189 } 190 191 /** 192 * Create the key object from the stored key tuple entry. 193 */ 194 public Object entryToObject(TupleInput input) { 195 196 try { 197 MarshalledKey key = (MarshalledKey) keyClass.newInstance(); 198 key.unmarshalKey(input); 199 return key; 200 } catch (IllegalAccessException e) { 201 throw new RuntimeExceptionWrapper(e); 202 } catch (InstantiationException e) { 203 throw new RuntimeExceptionWrapper(e); 204 } 205 } 206 207 /** 208 * Create the stored key tuple entry from the key object. 209 */ 210 public void objectToEntry(Object object, TupleOutput output) { 211 212 MarshalledKey key = (MarshalledKey) object; 213 key.marshalKey(output); 214 } 215 } 216 217 /** 218 * MarshalledEntityBinding is used to bind the stored key/data entry pair 219 * to a combined to an entity object representation. To do this, it calls 220 * the MarshalledEnt interface implemented by the entity class. 221 * 222 * <p> The binding is "tricky" in that it uses the entity class for both 223 * the stored data entry and the combined entity object. To do this, 224 * entity's key field(s) are transient and are set by the binding after the 225 * data object has been deserialized. This avoids the use of a "data" class 226 * completely. </p> 227 */ 228 private static class MarshalledEntityBinding extends TupleSerialBinding { 229 230 /** 231 * Construct the binding object. 232 */ 233 private MarshalledEntityBinding(ClassCatalog classCatalog, 234 Class entityClass) { 235 236 super(classCatalog, entityClass); 237 238 // The entity class will be used to instantiate the entity object. 239 // 240 if (!MarshalledEnt.class.isAssignableFrom(entityClass)) { 241 throw new IllegalArgumentException(entityClass.toString() + 242 " does not implement MarshalledEnt"); 243 } 244 } 245 246 /** 247 * Create the entity by combining the stored key and data. 248 * This "tricky" binding returns the stored data as the entity, but 249 * first it sets the transient key fields from the stored key. 250 */ 251 public Object entryToObject(TupleInput tupleInput, Object javaInput) { 252 253 MarshalledEnt entity = (MarshalledEnt) javaInput; 254 entity.unmarshalPrimaryKey(tupleInput); 255 return entity; 256 } 257 258 /** 259 * Create the stored key from the entity. 260 */ 261 public void objectToKey(Object object, TupleOutput output) { 262 263 MarshalledEnt entity = (MarshalledEnt) object; 264 entity.marshalPrimaryKey(output); 265 } 266 267 /** 268 * Return the entity as the stored data. There is nothing to do here 269 * since the entity's key fields are transient. 270 */ 271 public Object objectToData(Object object) { 272 273 return object; 274 } 275 } 276} 277