1 /*-
2  * Copyright (c) 2000, 2020 Oracle and/or its affiliates.  All rights reserved.
3  *
4  * See the file LICENSE for license information.
5  *
6  */
7 
8 package com.sleepycat.collections;
9 
10 import com.sleepycat.bind.EntryBinding;
11 import com.sleepycat.bind.serial.ClassCatalog;
12 import com.sleepycat.bind.serial.TupleSerialMarshalledBinding;
13 import com.sleepycat.bind.serial.TupleSerialMarshalledKeyCreator;
14 import com.sleepycat.bind.tuple.MarshalledTupleEntry; // for javadoc
15 import com.sleepycat.bind.tuple.MarshalledTupleKeyEntity;
16 import com.sleepycat.bind.tuple.TupleBinding;
17 import com.sleepycat.bind.tuple.TupleMarshalledBinding;
18 import com.sleepycat.db.Database;
19 
20 /**
21  * Creates stored collections having tuple keys and serialized entity values.
22  * The entity classes must be Serializable and must implement the
23  * MarshalledTupleKeyEntity interfaces.  The key classes must either implement
24  * the MarshalledTupleEntry interface or be one of the Java primitive type
25  * classes.  Underlying binding objects are created automatically.
26  *
27  * @author Mark Hayes
28  */
29 public class TupleSerialFactory {
30 
31     private ClassCatalog catalog;
32 
33     /**
34      * Creates a tuple-serial factory for given environment and class catalog.
35      *
36      * @param catalog the ClassCatalog.
37      */
TupleSerialFactory(ClassCatalog catalog)38     public TupleSerialFactory(ClassCatalog catalog) {
39 
40         this.catalog = catalog;
41     }
42 
43     /**
44      * Returns the class catalog associated with this factory.
45      *
46      * @return the catalog.
47      */
getCatalog()48     public final ClassCatalog getCatalog() {
49 
50         return catalog;
51     }
52 
53     /**
54      * Creates a map from a previously opened Database object.
55      *
56      * @param db the previously opened Database object.
57      *
58      * @param keyClass is the class used for map keys.  It must implement the
59      * {@link MarshalledTupleEntry} interface or be one of the Java primitive
60      * type classes.
61      *
62      * @param valueBaseClass the base class of the entity values for this
63      * store.  It must implement the  {@link MarshalledTupleKeyEntity}
64      * interface.
65      *
66      * @param writeAllowed is true to create a read-write collection or false
67      * to create a read-only collection.
68      *
69      * @param <K> the key class.
70      *
71      * @param <V> the value base class.
72      *
73      * @return the map.
74      */
75     public <K, V extends MarshalledTupleKeyEntity> StoredMap<K, V>
newMap(Database db, Class<K> keyClass, Class<V> valueBaseClass, boolean writeAllowed)76         newMap(Database db,
77                Class<K> keyClass,
78                Class<V> valueBaseClass,
79                boolean writeAllowed) {
80 
81         return new StoredMap<K, V>(db,
82                         getKeyBinding(keyClass),
83                         getEntityBinding(valueBaseClass),
84                         writeAllowed);
85     }
86 
87     /**
88      * Creates a sorted map from a previously opened Database object.
89      *
90      * @param db the previously opened Database object.
91      *
92      * @param keyClass is the class used for map keys.  It must implement the
93      * {@link MarshalledTupleEntry} interface or be one of the Java primitive
94      * type classes.
95      *
96      * @param valueBaseClass the base class of the entity values for this
97      * store.  It must implement the  {@link MarshalledTupleKeyEntity}
98      * interface.
99      *
100      * @param writeAllowed is true to create a read-write collection or false
101      * to create a read-only collection.
102      *
103      * @param <K> the key class.
104      *
105      * @param <V> the value base class.
106      *
107      * @return the sorted map.
108      */
109     public <K, V extends MarshalledTupleKeyEntity> StoredSortedMap<K, V>
newSortedMap(Database db, Class<K> keyClass, Class<V> valueBaseClass, boolean writeAllowed)110         newSortedMap(Database db,
111                      Class<K> keyClass,
112                      Class<V> valueBaseClass,
113                      boolean writeAllowed) {
114 
115         return new StoredSortedMap(db,
116                         getKeyBinding(keyClass),
117                         getEntityBinding(valueBaseClass),
118                         writeAllowed);
119     }
120 
121     /**
122      * Creates a <code>SecondaryKeyCreator</code> object for use in configuring
123      * a <code>SecondaryDatabase</code>.  The returned object implements
124      * the {@link com.sleepycat.db.SecondaryKeyCreator} interface.
125      *
126      * @param valueBaseClass the base class of the entity values for this
127      * store.  It must implement the  {@link MarshalledTupleKeyEntity}
128      * interface.
129      *
130      * @param keyName is the key name passed to the {@link
131      * MarshalledTupleKeyEntity#marshalSecondaryKey} method to identify the
132      * secondary key.
133      *
134      * @param <V> the value base class.
135      *
136      * @return the key creator.
137      */
138     public <V extends MarshalledTupleKeyEntity>
139         TupleSerialMarshalledKeyCreator<V>
getKeyCreator(Class<V> valueBaseClass, String keyName)140         getKeyCreator(Class<V> valueBaseClass, String keyName) {
141 
142         return new TupleSerialMarshalledKeyCreator<V>
143             (getEntityBinding(valueBaseClass), keyName);
144     }
145 
146     public <V extends MarshalledTupleKeyEntity>
147         TupleSerialMarshalledBinding<V>
getEntityBinding(Class<V> baseClass)148         getEntityBinding(Class<V> baseClass) {
149 
150         return new TupleSerialMarshalledBinding<V>(catalog, baseClass);
151     }
152 
getKeyBinding(Class<K> keyClass)153     private <K> EntryBinding<K> getKeyBinding(Class<K> keyClass) {
154 
155         EntryBinding<K> binding = TupleBinding.getPrimitiveBinding(keyClass);
156         if (binding == null) {
157 
158             /*
159              * Cannot use type param <K> here because it does not implement
160              * MarshalledTupleEntry if it is a primitive class.
161              */
162             binding = new TupleMarshalledBinding(keyClass);
163         }
164         return binding;
165     }
166 }
167