1 /*-
2  * Copyright (c) 2002, 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.persist;
9 
10 import com.sleepycat.db.DatabaseException;
11 import com.sleepycat.db.Environment; // for javadoc
12 import com.sleepycat.persist.evolve.IncompatibleClassException;
13 import com.sleepycat.persist.evolve.Mutations;
14 import com.sleepycat.persist.model.AnnotationModel;
15 import com.sleepycat.persist.model.EntityModel;
16 import com.sleepycat.persist.raw.RawStore; // for javadoc
17 
18 /**
19  * Configuration properties used with an {@link EntityStore} or {@link
20  * RawStore}.
21  *
22  * <p>{@code StoreConfig} objects are thread-safe.  Multiple threads may safely
23  * call the methods of a shared {@code StoreConfig} object.</p>
24  *
25  * <p>See the <a href="package-summary.html#example">package
26  * summary example</a> for an example of using a {@code StoreConfig}.</p>
27  *
28  * @author Mark Hayes
29  */
30 public class StoreConfig implements Cloneable {
31 
32     /**
33      * The default store configuration containing properties as if the
34      * configuration were constructed and not modified.
35      */
36     public static final StoreConfig DEFAULT = new StoreConfig();
37 
38     private boolean allowCreate;
39     private boolean checksum;
40     private boolean encrypted;
41     private boolean exclusiveCreate;
42     private boolean transactional;
43     private boolean readOnly;
44     private boolean secondaryBulkLoad;
45     private String password;
46     private EntityModel model;
47     private Mutations mutations;
48     private DatabaseNamer databaseNamer = DatabaseNamer.DEFAULT;
49 
50     /**
51      * Creates an entity store configuration object with default properties.
52      */
StoreConfig()53     public StoreConfig() {
54     }
55 
56     /**
57      * Returns a shallow copy of the configuration.
58      *
59      * @return the clone.
60      *
61      * @deprecated As of JE 4.0.13, replaced by {@link StoreConfig#clone()}.
62      */
63 	@Deprecated
cloneConfig()64     public StoreConfig cloneConfig() {
65         try {
66             return (StoreConfig) super.clone();
67         } catch (CloneNotSupportedException cannotHappen) {
68             return null;
69         }
70     }
71 
72     /**
73      * Returns a shallow copy of the configuration.
74      */
75     @Override
clone()76     public StoreConfig clone() {
77         try {
78             return (StoreConfig) super.clone();
79         } catch (CloneNotSupportedException cannotHappen) {
80             return null;
81         }
82     }
83 
84     /**
85      * Specifies whether creation of a new store is allowed.  By default this
86      * property is false.
87      *
88      * <p>If this property is false and the internal store metadata database
89      * does not exist, {@link DatabaseException} will be thrown when the store
90      * is opened.</p>
91      *
92      * @param allowCreate whether creation of a new store is allowed.
93      *
94      * @return 'this'.
95      */
setAllowCreate(boolean allowCreate)96     public StoreConfig setAllowCreate(boolean allowCreate) {
97         setAllowCreateVoid(allowCreate);
98         return this;
99     }
100 
101     /**
102      * The void return setter for use by Bean editors.
103      *
104      * @param allowCreate whether creation of a new store is allowed.
105      */
setAllowCreateVoid(boolean allowCreate)106     public void setAllowCreateVoid(boolean allowCreate) {
107         this.allowCreate = allowCreate;
108     }
109 
110     /**
111      * Returns whether creation of a new store is allowed.
112      *
113      * @return whether creation of a new store is allowed.
114      */
getAllowCreate()115     public boolean getAllowCreate() {
116         return allowCreate;
117     }
118 
119     /**
120      * Specifies whether opening an existing store is prohibited.  By default
121      * this property is false.
122      *
123      * <p>If this property is true and the internal store metadata database
124      * already exists, {@link DatabaseException} will be thrown when the store
125      * is opened.</p>
126      *
127      * @param exclusiveCreate whether opening an existing store is prohibited.
128      *
129      * @return 'this'.
130      */
setExclusiveCreate(boolean exclusiveCreate)131     public StoreConfig setExclusiveCreate(boolean exclusiveCreate) {
132         setExclusiveCreateVoid(exclusiveCreate);
133         return this;
134     }
135 
136     /**
137      * The void return setter for use by Bean editors.
138      *
139      * @param exclusiveCreate whether opening an existing store is prohibited.
140      */
setExclusiveCreateVoid(boolean exclusiveCreate)141     public void setExclusiveCreateVoid(boolean exclusiveCreate) {
142         this.exclusiveCreate = exclusiveCreate;
143     }
144 
145     /**
146      * Returns whether opening an existing store is prohibited.
147      *
148      * @return whether opening an existing store is prohibited.
149      */
getExclusiveCreate()150     public boolean getExclusiveCreate() {
151         return exclusiveCreate;
152     }
153 
154     /**
155      * Sets the transactional configuration property.  By default this property
156      * is false.
157      *
158      * <p>This property is true to open all store indices for transactional
159      * access.  True may not be specified if the environment is not also
160      * transactional.</p>
161      *
162      * @param transactional whether the store is transactional.
163      *
164      * @return 'this'.
165      */
setTransactional(boolean transactional)166     public StoreConfig setTransactional(boolean transactional) {
167         setTransactionalVoid(transactional);
168         return this;
169     }
170 
171     /**
172      * The void return setter for use by Bean editors.
173      *
174      * @param transactional whether the store is transactional.
175      */
setTransactionalVoid(boolean transactional)176     public void setTransactionalVoid(boolean transactional) {
177         this.transactional = transactional;
178     }
179 
180     /**
181      * Returns the transactional configuration property.
182      *
183      * @return whether the store is transactional.
184      */
getTransactional()185     public boolean getTransactional() {
186         return transactional;
187     }
188 
189     /**
190     Set the password used to perform encryption and decryption.
191     <p>
192     Because databases opened within environments use the password
193     specified to the environment, it is an error to attempt to set a
194     password in a database created within an environment.  To encrypt
195     a database within an encrypted environment use
196     {@link com.sleepycat.db.EnvironmentConfig#setEncrypted EnvironmentConfig.setEncrypted}
197     <p>
198     Berkeley DB uses the Rijndael/AES (also known as the Advanced
199     Encryption Standard and Federal Information Processing
200     Standard (FIPS) 197) algorithm for encryption or decryption.
201     @param password the password used to perform encryption and decryption
202     */
setEncrypted(final String password)203     public void setEncrypted(final String password) {
204         this.password = password;
205     }
206 
207     /**
208      * Enables encryption when the environment is also encrypted, see
209      * {@link com.sleepycat.db.EnvironmentConfig#setEncrypted EnvironmentConfig.setEncrypted}
210      * <p>
211      * To encrypt a database that does not use an environment, see
212      * {@link com.sleepycat.persist.StoreConfig#setEncrypted StoreConfig.setEncrypted}
213      * @param enable encryption on this database.
214      */
enableEncrypted(final boolean enable)215     public void enableEncrypted(final boolean enable) {
216     	this.encrypted = enable;
217     	this.checksum = enable;
218     }
219 
220     /**
221 Return true if the database has been configured to perform encryption.
222 <p>
223 This method may be called at any time during the life of the application.
224 <p>
225 @return
226 True if the database has been configured to perform encryption.
227     */
getEncrypted()228     public boolean getEncrypted() {
229         return (password != null || encrypted);
230     }
231 
232     /**
233      * Sets the read-only configuration property.  By default this property is
234      * false.
235      *
236      * <p>This property is true to open all store indices for read-only access,
237      * or false to open them for read-write access.  False may not be specified
238      * if the environment is read-only.</p>
239      *
240      * @param readOnly whether the store is read-only.
241      *
242      * @return 'this'.
243      */
setReadOnly(boolean readOnly)244     public StoreConfig setReadOnly(boolean readOnly) {
245         setReadOnlyVoid(readOnly);
246         return this;
247     }
248 
249     /**
250      * The void return setter for use by Bean editors.
251      *
252      * @param readOnly whether the store is read-only.
253      */
setReadOnlyVoid(boolean readOnly)254     public void setReadOnlyVoid(boolean readOnly) {
255         this.readOnly = readOnly;
256     }
257 
258     /**
259      * Returns the read-only configuration property.
260      *
261      * @return whether the store is read-only.
262      */
getReadOnly()263     public boolean getReadOnly() {
264         return readOnly;
265     }
266 
267 
268     /**
269      * Sets the bulk-load-secondaries configuration property.  By default this
270      * property is false.
271      *
272      * <p>This property is true to cause the initial creation of secondary
273      * indices to be performed as a bulk load.  If this property is true and
274      * {@link EntityStore#getSecondaryIndex EntityStore.getSecondaryIndex} has
275      * never been called for a secondary index, that secondary index will not
276      * be created or written as records are written to the primary index.  In
277      * addition, if that secondary index defines a foreign key constraint, the
278      * constraint will not be enforced.</p>
279      *
280      * <p>The secondary index will be populated later when the {@code
281      * getSecondaryIndex} method is called for the first time for that index,
282      * or when the store is closed and re-opened with this property set to
283      * false and the primary index is obtained.  In either case, the secondary
284      * index is populated by reading through the entire primary index and
285      * adding records to the secondary index as needed.  While populating the
286      * secondary, foreign key constraints will be enforced and an exception is
287      * thrown if a constraint is violated.</p>
288      *
289      * <p>When loading a primary index along with secondary indexes from a
290      * large input data set, configuring a bulk load of the secondary indexes
291      * is sometimes more performant than updating the secondary indexes each
292      * time the primary index is updated.  The absence of foreign key
293      * constraints during the load also provides more flexibility.</p>
294      *
295      * @param secondaryBulkLoad whether bulk-load-secondaries is used.
296      *
297      * @return 'this'.
298      */
setSecondaryBulkLoad(boolean secondaryBulkLoad)299     public StoreConfig setSecondaryBulkLoad(boolean secondaryBulkLoad) {
300         setSecondaryBulkLoadVoid(secondaryBulkLoad);
301         return this;
302     }
303 
304     /**
305      * The void return setter for use by Bean editors.
306      *
307      * @param secondaryBulkLoad whether bulk-load-secondaries is used.
308      */
setSecondaryBulkLoadVoid(boolean secondaryBulkLoad)309     public void setSecondaryBulkLoadVoid(boolean secondaryBulkLoad) {
310         this.secondaryBulkLoad = secondaryBulkLoad;
311     }
312 
313     /**
314      * Returns the bulk-load-secondaries configuration property.
315      *
316      * @return whether bulk-load-secondaries is used.
317      */
getSecondaryBulkLoad()318     public boolean getSecondaryBulkLoad() {
319         return secondaryBulkLoad;
320     }
321 
322     /**
323      * Sets the entity model that defines entity classes and index keys.
324      *
325      * <p>If null is specified or this method is not called, an {@link
326      * AnnotationModel} instance is used by default.</p>
327      *
328      * @param model the EntityModel.
329      *
330      * @return 'this'.
331      */
setModel(EntityModel model)332     public StoreConfig setModel(EntityModel model) {
333         setModelVoid(model);
334         return this;
335     }
336 
337     /**
338      * The void return setter for use by Bean editors.
339      *
340      * @param model the EntityModel.
341      */
setModelVoid(EntityModel model)342     public void setModelVoid(EntityModel model) {
343         this.model = model;
344     }
345 
346     /**
347      * Returns the entity model that defines entity classes and index keys.
348      *
349      * @return the EntityModel.
350      */
getModel()351     public EntityModel getModel() {
352         return model;
353     }
354 
355     /**
356      * Configures mutations for performing lazy evolution of stored instances.
357      * Existing mutations for this store are not cleared, so the mutations
358      * required are only those changes that have been made since the store was
359      * last opened.  Some new mutations may override existing specifications,
360      * and some may be supplemental.
361      *
362      * <p>If null is specified and the store already exists, the previously
363      * specified mutations are used.  The mutations are stored persistently in
364      * serialized form.</p>
365      *
366      * <p>Mutations must be available to handle all changes to classes that are
367      * incompatible with the class definitions known to this store.  See {@link
368      * Mutations} and {@link com.sleepycat.persist.evolve Class Evolution} for
369      * more information.</p>
370      *
371      * <p>If an incompatible class change has been made and mutations are not
372      * available for handling the change, {@link IncompatibleClassException}
373      * will be thrown when creating an {@link EntityStore}.</p>
374      *
375      * @param mutations the Mutations.
376      *
377      * @return 'this'.
378      */
setMutations(Mutations mutations)379     public StoreConfig setMutations(Mutations mutations) {
380         setMutationsVoid(mutations);
381         return this;
382     }
383 
384     /**
385      * The void return setter for use by Bean editors.
386      *
387      * @param mutations the Mutations.
388      */
setMutationsVoid(Mutations mutations)389     public void setMutationsVoid(Mutations mutations) {
390         this.mutations = mutations;
391     }
392 
393     /**
394      * Returns the configured mutations for performing lazy evolution of stored
395      * instances.
396      *
397      * @return the Mutations.
398      */
getMutations()399     public Mutations getMutations() {
400         return mutations;
401     }
402 
403     /**
404      * Specifies the object reponsible for naming of files and databases.
405      *
406      * By default this property is {@link DatabaseNamer#DEFAULT}.
407      *
408      * @param databaseNamer the DatabaseNamer.
409      *
410      * @return 'this'.
411      *
412      * @throws NullPointerException if a null parameter value is passed.
413      */
setDatabaseNamer(DatabaseNamer databaseNamer)414     public StoreConfig setDatabaseNamer(DatabaseNamer databaseNamer) {
415         setDatabaseNamerVoid(databaseNamer);
416         return this;
417     }
418 
419     /**
420      * The void return setter for use by Bean editors.
421      *
422      * @param databaseNamer the DatabaseNamer.
423      */
setDatabaseNamerVoid(DatabaseNamer databaseNamer)424     public void setDatabaseNamerVoid(DatabaseNamer databaseNamer) {
425         if (databaseNamer == null) {
426             throw new NullPointerException();
427         }
428         this.databaseNamer = databaseNamer;
429     }
430 
431     /**
432      * Returns the object reponsible for naming of files and databases.
433      *
434      * @return the DatabaseNamer.
435      */
getDatabaseNamer()436     public DatabaseNamer getDatabaseNamer() {
437         return databaseNamer;
438     }
439 
getPassword()440     public String getPassword() {
441     	return password;
442     }
443 }
444