001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: SampleViews.java,v 1.21.2.2 2008/01/07 15:14:02 cwl Exp $
007: */
008:
009: package collections.ship.marshal;
010:
011: import com.sleepycat.bind.EntityBinding;
012: import com.sleepycat.bind.EntryBinding;
013: import com.sleepycat.bind.serial.ClassCatalog;
014: import com.sleepycat.bind.serial.TupleSerialBinding;
015: import com.sleepycat.bind.tuple.TupleBinding;
016: import com.sleepycat.bind.tuple.TupleInput;
017: import com.sleepycat.bind.tuple.TupleOutput;
018: import com.sleepycat.collections.StoredSortedMap;
019: import com.sleepycat.collections.StoredSortedValueSet;
020: import com.sleepycat.util.RuntimeExceptionWrapper;
021:
022: /**
023: * SampleViews defines the data bindings and collection views for the sample
024: * database.
025: *
026: * @author Mark Hayes
027: */
028: public class SampleViews {
029:
030: private StoredSortedMap partMap;
031: private StoredSortedMap supplierMap;
032: private StoredSortedMap shipmentMap;
033: private StoredSortedMap shipmentByPartMap;
034: private StoredSortedMap shipmentBySupplierMap;
035: private StoredSortedMap supplierByCityMap;
036:
037: /**
038: * Create the data bindings and collection views.
039: */
040: public SampleViews(SampleDatabase db) {
041:
042: // Create the data bindings.
043: // In this sample, EntityBinding classes are used to bind the stored
044: // key/data entry pair to a combined data object; a "tricky" binding
045: // that uses transient fields is used--see PartBinding, etc, for
046: // details. For keys, a one-to-one binding is implemented with
047: // EntryBinding classes to bind the stored tuple entry to a key Object.
048: //
049: ClassCatalog catalog = db.getClassCatalog();
050: EntryBinding partKeyBinding = new MarshalledKeyBinding(
051: PartKey.class);
052: EntityBinding partDataBinding = new MarshalledEntityBinding(
053: catalog, Part.class);
054: EntryBinding supplierKeyBinding = new MarshalledKeyBinding(
055: SupplierKey.class);
056: EntityBinding supplierDataBinding = new MarshalledEntityBinding(
057: catalog, Supplier.class);
058: EntryBinding shipmentKeyBinding = new MarshalledKeyBinding(
059: ShipmentKey.class);
060: EntityBinding shipmentDataBinding = new MarshalledEntityBinding(
061: catalog, Shipment.class);
062: EntryBinding cityKeyBinding = TupleBinding
063: .getPrimitiveBinding(String.class);
064:
065: // Create map views for all stores and indices.
066: // StoredSortedMap is used since the stores and indices are ordered
067: // (they use the DB_BTREE access method).
068: //
069: partMap = new StoredSortedMap(db.getPartDatabase(),
070: partKeyBinding, partDataBinding, true);
071: supplierMap = new StoredSortedMap(db.getSupplierDatabase(),
072: supplierKeyBinding, supplierDataBinding, true);
073: shipmentMap = new StoredSortedMap(db.getShipmentDatabase(),
074: shipmentKeyBinding, shipmentDataBinding, true);
075: shipmentByPartMap = new StoredSortedMap(db
076: .getShipmentByPartDatabase(), partKeyBinding,
077: shipmentDataBinding, true);
078: shipmentBySupplierMap = new StoredSortedMap(db
079: .getShipmentBySupplierDatabase(), supplierKeyBinding,
080: shipmentDataBinding, true);
081: supplierByCityMap = new StoredSortedMap(db
082: .getSupplierByCityDatabase(), cityKeyBinding,
083: supplierDataBinding, true);
084: }
085:
086: // The views returned below can be accessed using the java.util.Map or
087: // java.util.Set interfaces, or using the StoredSortedMap and
088: // StoredValueSet classes, which provide additional methods. The entity
089: // sets could be obtained directly from the Map.values() method but
090: // convenience methods are provided here to return them in order to avoid
091: // down-casting elsewhere.
092:
093: /**
094: * Return a map view of the part storage container.
095: */
096: public StoredSortedMap getPartMap() {
097:
098: return partMap;
099: }
100:
101: /**
102: * Return a map view of the supplier storage container.
103: */
104: public StoredSortedMap getSupplierMap() {
105:
106: return supplierMap;
107: }
108:
109: /**
110: * Return a map view of the shipment storage container.
111: */
112: public StoredSortedMap getShipmentMap() {
113:
114: return shipmentMap;
115: }
116:
117: /**
118: * Return an entity set view of the part storage container.
119: */
120: public StoredSortedValueSet getPartSet() {
121:
122: return (StoredSortedValueSet) partMap.values();
123: }
124:
125: /**
126: * Return an entity set view of the supplier storage container.
127: */
128: public StoredSortedValueSet getSupplierSet() {
129:
130: return (StoredSortedValueSet) supplierMap.values();
131: }
132:
133: /**
134: * Return an entity set view of the shipment storage container.
135: */
136: public StoredSortedValueSet getShipmentSet() {
137:
138: return (StoredSortedValueSet) shipmentMap.values();
139: }
140:
141: /**
142: * Return a map view of the shipment-by-part index.
143: */
144: public StoredSortedMap getShipmentByPartMap() {
145:
146: return shipmentByPartMap;
147: }
148:
149: /**
150: * Return a map view of the shipment-by-supplier index.
151: */
152: public StoredSortedMap getShipmentBySupplierMap() {
153:
154: return shipmentBySupplierMap;
155: }
156:
157: /**
158: * Return a map view of the supplier-by-city index.
159: */
160: public final StoredSortedMap getSupplierByCityMap() {
161:
162: return supplierByCityMap;
163: }
164:
165: /**
166: * MarshalledKeyBinding is used to bind the stored key tuple entry to a key
167: * object representation. To do this, it calls the MarshalledKey interface
168: * implemented by the key class.
169: */
170: private static class MarshalledKeyBinding extends TupleBinding {
171:
172: private Class keyClass;
173:
174: /**
175: * Construct the binding object.
176: */
177: private MarshalledKeyBinding(Class keyClass) {
178:
179: // The key class will be used to instantiate the key object.
180: //
181: if (!MarshalledKey.class.isAssignableFrom(keyClass)) {
182: throw new IllegalArgumentException(keyClass.toString()
183: + " does not implement MarshalledKey");
184: }
185: this .keyClass = keyClass;
186: }
187:
188: /**
189: * Create the key object from the stored key tuple entry.
190: */
191: public Object entryToObject(TupleInput input) {
192:
193: try {
194: MarshalledKey key = (MarshalledKey) keyClass
195: .newInstance();
196: key.unmarshalKey(input);
197: return key;
198: } catch (IllegalAccessException e) {
199: throw new RuntimeExceptionWrapper(e);
200: } catch (InstantiationException e) {
201: throw new RuntimeExceptionWrapper(e);
202: }
203: }
204:
205: /**
206: * Create the stored key tuple entry from the key object.
207: */
208: public void objectToEntry(Object object, TupleOutput output) {
209:
210: MarshalledKey key = (MarshalledKey) object;
211: key.marshalKey(output);
212: }
213: }
214:
215: /**
216: * MarshalledEntityBinding is used to bind the stored key/data entry pair
217: * to a combined to an entity object representation. To do this, it calls
218: * the MarshalledEntity interface implemented by the entity class.
219: *
220: * <p> The binding is "tricky" in that it uses the entity class for both
221: * the stored data entry and the combined entity object. To do this,
222: * entity's key field(s) are transient and are set by the binding after the
223: * data object has been deserialized. This avoids the use of a "data" class
224: * completely. </p>
225: */
226: private static class MarshalledEntityBinding extends
227: TupleSerialBinding {
228:
229: /**
230: * Construct the binding object.
231: */
232: private MarshalledEntityBinding(ClassCatalog classCatalog,
233: Class entityClass) {
234:
235: super (classCatalog, entityClass);
236:
237: // The entity class will be used to instantiate the entity object.
238: //
239: if (!MarshalledEntity.class.isAssignableFrom(entityClass)) {
240: throw new IllegalArgumentException(entityClass
241: .toString()
242: + " does not implement MarshalledEntity");
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,
252: Object javaInput) {
253:
254: MarshalledEntity entity = (MarshalledEntity) javaInput;
255: entity.unmarshalPrimaryKey(tupleInput);
256: return entity;
257: }
258:
259: /**
260: * Create the stored key from the entity.
261: */
262: public void objectToKey(Object object, TupleOutput output) {
263:
264: MarshalledEntity entity = (MarshalledEntity) object;
265: entity.marshalPrimaryKey(output);
266: }
267:
268: /**
269: * Return the entity as the stored data. There is nothing to do here
270: * since the entity's key fields are transient.
271: */
272: public Object objectToData(Object object) {
273:
274: return object;
275: }
276: }
277: }
|