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