|
Holger's Java API |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectcom.antelmann.db.WrappedDBClassStore<T>
public class WrappedDBClassStore<T extends DBEntry>
a generic DBClassStore wrapper easing the implementation of special wrappers.
In addition to make it easy to just implement some methods, there are also
some convenient method implementations that provide some generally useful functionality.
WrappedDBClassStore instances are also supported by AbstractDatabase.queryStoreForInterface(Class, Class),
so that the interfaces of the embedded store can also be exposed via that method without having to inherit and
implement and then delegate the methods for an interface.
AbstractDatabase.queryStoreForInterface(Class, Class)| Nested Class Summary |
|---|
| Nested classes/interfaces inherited from interface com.antelmann.db.DBClassStore |
|---|
DBClassStore.DBMethod |
| Field Summary | |
|---|---|
protected DBClassStore<T> |
store
access to the embedded original store; only the constructor should change this value |
| Constructor Summary | |
|---|---|
protected |
WrappedDBClassStore()
when using this constructor, the embedded store must still be initialized. |
|
WrappedDBClassStore(DBClassStore<T> store)
|
| Method Summary | ||
|---|---|---|
void |
add(Processor<T,? extends DatabaseException> p)
|
|
protected void |
checkReadAccess()
overwrite this method to further restrict read access (based on the current user for example) |
|
protected void |
checkWriteAccess()
overwrite this method to further restrict write access (based on the current user for example) |
|
boolean |
containsID(Object id)
determines whether the given ID is present in this store. |
|
int |
deleteEntries(Filter<? super T> filter)
deletes all DBEntry objects that match the given filter; if the filter is null, all resources are deleted. |
|
protected int |
deleteEntriesIndividually(Filter<? super T> filter)
deletes all applicable entries by instantiating them and then call deleteEntry(Object)
on each entries. |
|
boolean |
deleteEntry(Object id)
removes the entry with the given ID from this store in the database. |
|
boolean |
exposesInterfaces()
if true (the default), AbstractDatabase.queryStoreForInterface(Class, Class)
will expose the interfaces of the internal store |
|
DBEnumeration<T> |
fetch(Filter<? super T> filter)
allows to retrieve the entries of this storage via iteration. |
|
DBEnumeration<Stub<T>> |
fetchStubs(Filter<? super Stub<?>> filter)
allows to access objects from this store w/o having to instantiate the entire original objects, but instead use Stubs to be able to display the list properly for selection. |
|
Object |
generateNewID()
this method is to generate unique new IDs for the DBEntry at hand - if the application has no other specific way of providing new IDs for this implementation. |
|
Filter<? super T> |
getAccessFilter()
|
|
Filter<? super Stub<?>> |
getAccessStubFilter()
|
|
Database<?> |
getDatabase()
provides access to the database instance that also coordinates the transaction management. |
|
T |
getEntry(Object id)
returns the DBEntry based on its ID. |
|
Class<T> |
getEntryClass()
returns the runtime class type this store represents |
|
Processor<T,? extends DatabaseException> |
getFetchProcessor()
|
|
Handler<T,? extends DatabaseException> |
getPreStoreHandler()
|
|
Handler<T,? extends DatabaseException> |
getStoreHandler()
|
|
Stub<T> |
getStub(Object id)
returns a Stub representing the resource for the given ID or null. |
|
Processor<Stub<T>,? extends DatabaseException> |
getStubProcessor()
|
|
void |
insert(T entry)
it is suggested to create the entry with an ID obtained through generateNewID() before passing it into
this method. |
|
Object |
insertAsNew(T entry)
inserts the given entry using an ID generated by generateNewID
while ignoring the ID of the given entry. |
|
boolean |
isApplyFilterProcessingRecursively()
|
|
boolean |
isDeleteEntriesIndividually()
|
|
boolean |
isEnsureTransactionsOnFetch()
|
|
boolean |
isProcessBeforeFiltering()
false by default; see setProcessBeforeFiltering(boolean) |
|
|
queryForInterface(Class<I> desiredInterface)
|
|
boolean |
remove(Processor<T,? extends DatabaseException> p)
|
|
void |
setAccessFilter(Filter<? super T> accessFilter)
allows to provide a filter that will limit access to the content of the store in regards to all read and write operations. |
|
void |
setAccessStubFilter(Filter<? super Stub<?>> accessStubFilter)
allows to not only filter entries themselves but also their respective stubs if applicable |
|
void |
setApplyFilterProcessingRecursively(boolean flag)
|
|
void |
setDeleteEntriesIndividually(boolean flag)
|
|
void |
setEnsureTransactionsOnFetch(boolean flag)
|
|
void |
setExposesInterfaces(boolean flag)
controls whether AbstractDatabase.queryStoreForInterface(Class, Class)
should expose the interfaces of the internally embedded store |
|
void |
setFetchProcessor(Processor<T,? extends DatabaseException> fetchProcessor)
|
|
void |
setPreStoreHandler(Handler<T,? extends DatabaseException> preStoreHandler)
|
|
void |
setProcessBeforeFiltering(boolean flag)
This setting only applies if the embedded store doesn't support ProcessorHook, which is preferred over using this method,
because several hassles can be avoided that way (see below). |
|
void |
setProcessBeforeFiltering(boolean flag,
boolean recursively)
|
|
void |
setStoreHandler(Handler<T,? extends DatabaseException> storeHandler)
|
|
void |
setStubProcessor(Processor<Stub<T>,? extends DatabaseException> stubProcessor)
|
|
int |
size(Filter<? super T> filter)
returns the total number of T elements in this store based on the given filter (which may be null) |
|
DBClassStore<T> |
unwrap()
returns the embedded instance that this wrapper encloses |
|
void |
update(T entry)
updates the given entry in the database. |
|
protected
|
wrapFilterForProcessing(Filter<? super X> filter,
Processor<X,? extends DatabaseException> p)
This method is only used if setProcessBeforeFiltering(boolean)
is set to true. |
|
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
protected DBClassStore<T extends DBEntry> store
| Constructor Detail |
|---|
protected WrappedDBClassStore()
storepublic WrappedDBClassStore(DBClassStore<T> store)
| Method Detail |
|---|
public final Database<?> getDatabase()
DBClassStore
getDatabase in interface DBClassStore<T extends DBEntry>public final Class<T> getEntryClass()
DBClassStore
getEntryClass in interface DBClassStore<T extends DBEntry>public DBClassStore<T> unwrap()
Wrapped
unwrap in interface Wrapped<DBClassStore<T extends DBEntry>>public final Filter<? super T> getAccessFilter()
setAccessFilter(Filter)public void setAccessFilter(Filter<? super T> accessFilter)
deleteEntries(Filter),
the option setDeleteEntriesIndividually(boolean) should be set to true.
The size(Filter) method remains unaffected.
setAccessStubFilter(Filter)public final Filter<? super Stub<?>> getAccessStubFilter()
public void setAccessStubFilter(Filter<? super Stub<?>> accessStubFilter)
setAccessFilter(Filter)public final boolean exposesInterfaces()
AbstractDatabase.queryStoreForInterface(Class, Class)
will expose the interfaces of the internal store
setExposesInterfaces(boolean)public void setExposesInterfaces(boolean flag)
AbstractDatabase.queryStoreForInterface(Class, Class)
should expose the interfaces of the internally embedded store
public final boolean isEnsureTransactionsOnFetch()
public void setEnsureTransactionsOnFetch(boolean flag)
public final boolean isDeleteEntriesIndividually()
public void setDeleteEntriesIndividually(boolean flag)
public final Processor<T,? extends DatabaseException> getFetchProcessor()
@Warning(value="depending on the settings, the processor may not run before filtering during fetch occurs") public void setFetchProcessor(Processor<T,? extends DatabaseException> fetchProcessor)
setProcessBeforeFiltering(boolean),
ProcessorHookpublic final Processor<Stub<T>,? extends DatabaseException> getStubProcessor()
@Warning(value="note that processing may influence filtering") public void setStubProcessor(Processor<Stub<T>,? extends DatabaseException> stubProcessor)
public final Handler<T,? extends DatabaseException> getStoreHandler()
public void setStoreHandler(Handler<T,? extends DatabaseException> storeHandler)
public final Handler<T,? extends DatabaseException> getPreStoreHandler()
public void setPreStoreHandler(Handler<T,? extends DatabaseException> preStoreHandler)
public boolean containsID(Object id)
throws DatabaseException
DBClassStore
containsID in interface DBClassStore<T extends DBEntry>DatabaseException
public boolean deleteEntry(Object id)
throws DatabaseException
DBClassStore
deleteEntry in interface DBClassStore<T extends DBEntry>DatabaseException
public int deleteEntries(Filter<? super T> filter)
throws DatabaseException
DBClassStoreDBClassStore.deleteEntry(Object)
is called for each entry passing the filter (although stores may choose to do so)!
Consequently, if a store's implementation does not call DBClassStore.deleteEntry(Object)
on each instance, calling this method may result in changes that are hard to monitor
for versioning purposes.
deleteEntries in interface DBClassStore<T extends DBEntry>DatabaseExceptionsetProcessBeforeFiltering(boolean)
protected int deleteEntriesIndividually(Filter<? super T> filter)
throws DatabaseException
deleteEntry(Object)
on each entries.
DatabaseException
public Object generateNewID()
throws DatabaseException,
UnsupportedOperationException
DBClassStore
generateNewID in interface DBClassStore<T extends DBEntry>DatabaseException
UnsupportedOperationExceptionSessionIdGenerator,
DBEntry.getID()
public void insert(T entry)
throws DatabaseException
DBClassStoregenerateNewID() before passing it into
this method.
The ID of the entry must not already exist in the database.
insert in interface DBClassStore<T extends DBEntry>DatabaseExceptionDBClassStore.generateNewID()
public Object insertAsNew(T entry)
throws DatabaseException,
UnsupportedOperationException
DBClassStoregenerateNewID
while ignoring the ID of the given entry.
With this method, the same Object (with the same ID) can be inserted
multiple times, stored with a new ID on each call; the ID creation is handled
automatically.
This is an optional feature that might not be implemented in all cases.
insertAsNew in interface DBClassStore<T extends DBEntry>DatabaseException
UnsupportedOperationExceptionDBEntry.getID(),
DBClassStore.generateNewID()
public void update(T entry)
throws DatabaseException
DBClassStore
update in interface DBClassStore<T extends DBEntry>DatabaseException - if the database was not able to perform the update
or it the entry didn't exist in the database before calling this methodpublic final boolean isProcessBeforeFiltering()
setProcessBeforeFiltering(boolean)
isProcessBeforeFiltering in interface ProcessedFilterOption<T extends DBEntry>public void setProcessBeforeFiltering(boolean flag)
ProcessorHook, which is preferred over using this method,
because several hassles can be avoided that way (see below).
By default, this option is set to false.
As a result, entries/stubs are not processed when running through a filter
during fetch operations.
Unfortunately, setting this option to true has a few other drawbacks!
First, a given CascadingFilter is actually altered when used for fetching,
so you better must not reuse such a filter passed to the store interface.
Second, a processor that returns another object than the one given will lead to
the processed object to not be returned by the DBEnumeration anymore
in case of a fetch.
Third, Problems may arise if a store implementation calls the filter twice on the same instance;
because in this case, the processor is called multiple times on the same entry -
which may or may not be a problem based on the processor's implementation
(other than just performance).
Another problem may arise with special filters where the accept method is never
actually called by the implementation.
Last but not least in the line of problems:
DatabaseExceptions thrown during processing are masked as RuntimeExceptions
within the accept-method of the filter.
setProcessBeforeFiltering in interface ProcessedFilterOption<T extends DBEntry>wrapFilterForProcessing(Filter, Processor),
setProcessBeforeFiltering(boolean, boolean),
isApplyFilterProcessingRecursively()
public void setProcessBeforeFiltering(boolean flag,
boolean recursively)
public final boolean isApplyFilterProcessingRecursively()
public void setApplyFilterProcessingRecursively(boolean flag)
@Warning(value="depending on processBeforeFiltering, filter may either be altered or entry may not be processed before filtering")
public DBEnumeration<T> fetch(Filter<? super T> filter)
throws DatabaseException
DBClassStoreAs all relevant entries may not completely fit into memory, an Enumeration is returned instead of a list. To directly get all entries as a list (and thus avoid concurrency problems), consider using methods from AbstractIterator to quickly retrieve all resources before processing them.
Be aware that the result of the enumeration may become undefined if data is inserted/deleted/updated while the elements are accessed. To guarantee consistency, all access to the returned Enumeration must be externally synchronized by holding the monitor of the database transaction throughout maintaining the Enumeration.
Note that you may have IterationExceptions being thrown on calling methods on the returned Enumeration, which are caused by either DatabaseExceptions or InstantiationExceptions on trying to fetch the next element, as not all possible errors may be caught on calling this method (as it possibly cannot instantiate all entries in advance).
All access to the returned Enumeration must be made within an active transaction.
As the returned Enumeration may hold resources to the database while iterating, the caller must ensure that these resources can be properly release. This is usually achieved by simply completely iterating through the return value, in which case the DBEnumeration is expected to properly clean up automatically. But in cases where the caller doesn't intend to go all the way through the Enumeration, the caller has to clean up explicitly, which can be done by calling the close() method on the returned DBEnumeration.
fetch in interface DBClassStore<T extends DBEntry>filter - may be null, in which case all entries from are returned.
DatabaseExceptionsetProcessBeforeFiltering(boolean)
@Warning(value="depending on processBeforeFiltering, filter may either be altered or entry may not be processed before filtering")
public DBEnumeration<Stub<T>> fetchStubs(Filter<? super Stub<?>> filter)
throws DatabaseException
DBClassStorefetch(Filter) .
fetchStubs in interface DBClassStore<T extends DBEntry>DatabaseExceptionsetProcessBeforeFiltering(boolean)
@Todo(value="find a solution that does not require altering the given filter but still allows for recognition of special filters and also takes care of a processor that may return a different object identity")
@Warning(value="filter may be altered as a result of embedding processing")
protected <X> Filter<X> wrapFilterForProcessing(Filter<? super X> filter,
Processor<X,? extends DatabaseException> p)
setProcessBeforeFiltering(boolean)
is set to true.
In case of a CascadingFilter, this implementation
places the processing into an inner filter, so that special filters
(that must inherit from CascadingFilter of course)
can still be recognized by the embedded store's implementation
for special performance optimization options; as a nasty side-effect,
the given filter is consequently altered and is better not to be used hereafter.
filter - the original filtersetProcessBeforeFiltering(boolean),
fetch(Filter),
fetchStubs(Filter),
deleteEntries(Filter),
size(Filter),
CascadingFilter
public T getEntry(Object id)
throws DatabaseException
DBClassStore
getEntry in interface DBClassStore<T extends DBEntry>id - the ID that is retrieved from Resource.getID()
DatabaseExceptionDBEntry.getID()
public Stub<T> getStub(Object id)
throws DatabaseException
DBClassStore
getStub in interface DBClassStore<T extends DBEntry>DatabaseException
public int size(Filter<? super T> filter)
throws DatabaseException
DBClassStore
size in interface DBClassStore<T extends DBEntry>filter - if non-null, only those elements will be counted that are applicable to the filter
DatabaseExceptionsetProcessBeforeFiltering(boolean)public <I> I queryForInterface(Class<I> desiredInterface)
AbstractDatabase.queryStoreForInterface(Class, Class)
protected void checkReadAccess()
throws DBAccessDeniedWarning
DBAccessDeniedWarning
protected void checkWriteAccess()
throws DBAccessDeniedWarning
DBAccessDeniedWarningpublic void add(Processor<T,? extends DatabaseException> p)
add in interface ProcessorHook<T extends DBEntry,DatabaseException>public boolean remove(Processor<T,? extends DatabaseException> p)
remove in interface ProcessorHook<T extends DBEntry,DatabaseException>
|
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||