Class MetadataSource
- All Implemented Interfaces:
AutoCloseable
- Direct Known Subclasses:
MetadataFallback
,MetadataWriter
id
is the primary key value for the desired record in the Format
table.
Properties
The constructor expects three Java arguments (the metadata standard, the data source and the database schema) completed by an arbitrary amount of optional arguments given as a map of properties. The following keys are recognized byMetadataSource
and all other entries are ignored:
Key | Value type | Description |
---|---|---|
"catalog" | String | The database catalog where the metadata schema is stored. |
"classloader" | ClassLoader | The class loader to use for creating Proxy instances. |
"maxStatements" | Integer | Maximal number of PreparedStatement s that can be kept simultaneously open. |
Concurrency
MetadataSource
is thread-safe but is not concurrent. If concurrency is desired,
multiple instances of MetadataSource
can be created for the same DataSource
.
The MetadataSource(MetadataSource)
convenience constructor can be used for this purpose.- Since:
- 0.8
- Version:
- 1.2
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate final class
A task to be executed later for closing all expiredCachedStatement
. -
Field Summary
FieldsModifier and TypeFieldDescription(package private) final String
The catalog, ornull
if none.private final ClassLoader
The class loader to use for creatingProxy
instances.private Connection
The connection to the database, ornull
if not yet created or if closed.private final DataSource
The data source object for fetching the connection to the database.private static final int
An extra delay to add to theTIMEOUT
in order to increase the chances to close many statements at once.private SQLBuilder
A helper class used for constructing SQL statements.(package private) static final String
The column name used for the identifiers.private static MetadataSource
The instance connected to the"jdbc/SpatialMetadata"
database, created when first needed and cleared when the classpath change.private boolean
Whether at least oneMetadataSource.CloseTask
is scheduled for execution.private final ThreadLocal
<LookupInfo> Some information about last used objects.private Filter
Where to report the warnings before to eventually log them.(package private) static final KeyNamePolicy
The policy for column names.private final WeakValueHashMap
<CacheKey, Object> The objects which have been created by a previous call tolookup(Class, String)
.private boolean
Whether thehelper
should quote schemas in SQL statements.private String
The database schema where metadata are stored, ornull
if none.protected final MetadataStandard
The metadata standard to be used for constructing the database schema.private final CachedStatement[]
A pool of prepared statements with a maximal capacity equals to the array length.All columns found in tables that have been queried or created up to date.private static final long
The timeout before to close a prepared statement, in nanoseconds. -
Constructor Summary
ConstructorsConstructorDescriptionForMetadataFallback
constructor only.MetadataSource
(MetadataStandard standard, DataSource dataSource, String schema, Map<String, ?> properties) Creates a new metadata source.MetadataSource
(MetadataSource source) Creates a new metadata source with the same configuration than the given source. -
Method Summary
Modifier and TypeMethodDescriptionasValueMap
(Object metadata) Returns a view of the given metadata as a map.void
close()
Closes the database connection used by this object.(package private) final void
Executed in a background thread for closing statements after their expiration time.private void
closeQuietly
(AutoCloseable resource) Closes the given resource without throwing exception.(package private) final Connection
Returns the connection to the database, creating a new one if needed.(package private) static Object
extractFromCollection
(Object value) If the given value is a collection, returns the first element in that collection ornull
if empty.(package private) static org.opengis.util.CodeList
<?> getCodeList
(Class<?> type, String name) Returns the code of the given type and name.getExistingColumns
(String table) Returns the set of all columns in a table, or an empty set if none (nevernull
).(package private) final LookupInfo
getLookupInfo
(Class<?> type) Gets theLookupInfo
instance for call to thereadColumn(LookupInfo, Method, Dispatcher)
method.static MetadataSource
Returns the metadata source connected to the"jdbc/SpatialMetadata"
database.(package private) static String
getTableName
(Class<?> type) Returns the table name for the specified class.Returns the current warning filter.(package private) final SQLBuilder
helper()
Returns a helper class for building SQL statements.(package private) final void
install()
If the metadata schema does not exist in the database, creates it and inserts the predefined metadata values.private Object
Implementation of publiclookup(Class, String)
method.<T> T
Returns an implementation of the specified metadata interface filled with the data referenced by the specified identifier.private CachedStatement
prepareStatement
(Class<?> type, String tableName, int preferredIndex) Returns a statement that can be reused for performing queries on the table for the specified interface.(package private) final String
If the given metadata is a proxy generated by thisMetadataSource
, returns the identifier of that proxy.(package private) final Object
readColumn
(LookupInfo info, Method method, Dispatcher toSearch) Invoked byMetadataProxy
for fetching an attribute value from a table.private int
recycle
(CachedStatement statement, int preferredIndex) Flags the givenCachedStatement
as available for reuse.private void
Schedules a task for closing the statements and the connection, if no such task is scheduled.(package private) final String
schema()
Returns the database schema where metadata are stored, ornull
if none.Searches for the given metadata in the database.(package private) final String
search
(String table, Set<String> columns, Map<String, Object> metadata, Statement stmt, SQLBuilder helper) Searches for the given metadata in the database.setWarningFilter
(Filter filter) Sets a filter to be notified when a warning occurred while reading from or writing metadata.private static <E> Collection
<?> specialize
(Collection<?> collection, Class<?> returnType, Class<E> elementType) Copies the given collection into the bestSet
implementation if possible, or returns the given collection unchanged otherwise.(package private) static Object
toStorableValue
(Object value) Converts the given object to a value that can be stored in the database.(package private) final void
warning
(Class<? extends MetadataSource> source, String method, LogRecord record) Reports a warning.
-
Field Details
-
NAME_POLICY
The policy for column names. We use UML identifiers (e.g."title"
) as defined by the metadata standard (typically ISO 19115). -
ID_COLUMN
The column name used for the identifiers.- See Also:
-
TIMEOUT
private static final long TIMEOUTThe timeout before to close a prepared statement, in nanoseconds. This is set to 2 seconds, which is a bit short but should be okay if theDataSource
creates pooled connections. In case there is no connection pool, then the mechanism defined in this package will hopefully keeps the performance at a reasonable level.- See Also:
-
EXTRA_DELAY
private static final int EXTRA_DELAYAn extra delay to add to theTIMEOUT
in order to increase the chances to close many statements at once.- See Also:
-
standard
The metadata standard to be used for constructing the database schema. -
dataSource
The data source object for fetching the connection to the database. This is specified at construction time. -
connection
The connection to the database, ornull
if not yet created or if closed. This field is set to a non-null value whenconnection()
is invoked, then closed and set tonull
after all cached statements have been closed.- See Also:
-
statements
A pool of prepared statements with a maximal capacity equals to the array length. The array length should be reasonably small. The array may contain null element anywhere. Inactive statements are closed after some timeout.Note: this array duplicates the work done by statement pools in modern JDBC drivers. Nevertheless it still useful in our case since we retain some additional JDBC resources together with theEvery access to this array must be synchronized onPreparedStatement
, for example theResultSet
created from that statement.MetadataSource.this
. Execution of a prepared statement may also need to be done inside the synchronized block, because a single JDBC connection cannot be assumed thread-safe.Usage example:
- See Also:
-
catalog
The catalog, ornull
if none. -
schema
The database schema where metadata are stored, ornull
if none. In the metadata source provided by SIS, this is"metadata"
or"METADATA"
, depending on the database convention regarding lower case / upper case identifiers.Consider this field as final. This field is modified only by
install()
for taking in account the lower case or upper case convention of the database engine. -
quoteSchema
private boolean quoteSchemaWhether thehelper
should quote schemas in SQL statements. A value offalse
let the database engine chooses its own lower case / upper case policy. This flag istrue
if the schema was specified by the user, orfalse
if using the metadata provided by SIS.Consider this field as final. This field is modified only by
install()
.- See Also:
-
helper
A helper class used for constructing SQL statements. This helper is created when first needed, then kept until the connection is closed.- See Also:
-
tableColumns
All columns found in tables that have been queried or created up to date. Keys are table names and values are the columns defined for that table.- See Also:
-
classloader
The class loader to use for creatingProxy
instances.- See Also:
-
pool
The objects which have been created by a previous call tolookup(Class, String)
. Used in order to share existing instances for the same interface and primary key.- See Also:
-
lastUsed
Some information about last used objects. Cached on assumption that the same information will be used more than once before to move to another metadata object. -
logFilter
Where to report the warnings before to eventually log them.- See Also:
-
isCloseScheduled
private boolean isCloseScheduledWhether at least oneMetadataSource.CloseTask
is scheduled for execution.- See Also:
-
instance
The instance connected to the"jdbc/SpatialMetadata"
database, created when first needed and cleared when the classpath change. May beMetadataFallback.INSTANCE
if we failed to establish a connection to the database for a non-transient reason.
-
-
Constructor Details
-
MetadataSource
public MetadataSource(MetadataStandard standard, DataSource dataSource, String schema, Map<String, ?> properties) Creates a new metadata source. The metadata standard to implement (typically ISO 19115, but not necessarily) and the database source are mandatory information. All other information are optional and can benull
.- Parameters:
standard
- the metadata standard to implement.dataSource
- the source for getting a connection to the database.schema
- the database schema were metadata tables are stored, ornull
if none.properties
- additional options, ornull
if none. See class javadoc for a description.
-
MetadataSource
Creates a new metadata source with the same configuration than the given source. The twoMetadataSource
instances will share the sameDataSource
but will use their ownConnection
. This constructor is useful when concurrency is desired.The new
MetadataSource
initially contains the warning filter declared in the givensource
.- Parameters:
source
- the source from which to copy the configuration.
-
MetadataSource
MetadataSource()ForMetadataFallback
constructor only.
-
-
Method Details
-
getProvided
Returns the metadata source connected to the"jdbc/SpatialMetadata"
database. In a default Apache SIS installation, this metadata source contains predefined records for some commonly used citations and formats among others.If connection to the metadata database cannot be established, then this method returns a fallback with a few hard-coded values.
- Returns:
- source of predefined metadata records from the
"jdbc/SpatialMetadata"
database.
-
install
If the metadata schema does not exist in the database, creates it and inserts the predefined metadata values. The current implementation has the following restrictions:- Metadata standard must be
MetadataStandard.ISO_19115
or compatible. - The schema name must be
"metadata"
, as this is the name used unquoted in SQL scripts.
non-free:sis-embedded-data
module. If we make this method public in a future Apache SIS version, then we can remove the reflection code.- Throws:
SQLException
- if an error occurred while inserting the metadata.IOException
- Metadata standard must be
-
connection
Returns the connection to the database, creating a new one if needed. This method shall be invoked inside a synchronized block wider than just the scope of this method in order to ensure that the connection is used by only one thread at time. This is also necessary for preventing the background thread to close the connection too early.Callers shall not close the connection returned by this method. The connection will be closed by
closeExpired()
after an arbitrary timeout.- Returns:
- the connection to the database.
- Throws:
SQLException
- if an error occurred while fetching the connection.
-
schema
Returns the database schema where metadata are stored, ornull
if none. -
helper
Returns a helper class for building SQL statements.- Throws:
SQLException
-
prepareStatement
private CachedStatement prepareStatement(Class<?> type, String tableName, int preferredIndex) throws SQLException Returns a statement that can be reused for performing queries on the table for the specified interface. Callers must invoke this method in a block synchronized onthis
.- Parameters:
type
- the interface for which to reuse a prepared statement.tableName
- value ofgetTableName(type)
, ornull
for computing by this method.preferredIndex
- index in the cache array where to search first. This is only a hint for increasing the chances to find quickly aCachedStatement
instance for the right type and identifier.- Throws:
SQLException
-
recycle
Flags the givenCachedStatement
as available for reuse.- Parameters:
statement
- the prepared statement to cache.preferredIndex
- index in the cache array to use if the corresponding slot is available.- Returns:
- index in the cache array where the result has been actually stored.
- Throws:
SQLException
-
getTableName
Returns the table name for the specified class. This is usually the ISO 19115 name, but we fallback on the simple class name if the ISO name is not available. The package prefix is omitted (e.g."CI_"
in"CI_Citation"
since newer ISO standards tend to drop it. -
proxy
If the given metadata is a proxy generated by thisMetadataSource
, returns the identifier of that proxy. Such metadata do not need to be inserted again in the database.- Parameters:
metadata
- the metadata to test.- Returns:
- the identifier (primary key), or
null
if the given metadata is not a proxy.
-
asValueMap
Returns a view of the given metadata as a map. This method returns always a map using UML identifier and containing all entries including the null ones because theMetadataSource
implementation assumes so.- Parameters:
metadata
- the metadata object to view as a map.- Returns:
- a map view over the metadata object.
- Throws:
ClassCastException
- if the metadata object does not implement a metadata interface of the expected package.
-
extractFromCollection
If the given value is a collection, returns the first element in that collection ornull
if empty.- Parameters:
value
- the value to inspect (can benull
).- Returns:
- the given value, or its first element if the value is a collection,
or
null
if the given value is null or an empty collection.
-
search
Searches for the given metadata in the database. If such metadata is found, then its identifier (primary key) is returned. Otherwise this method returnsnull
.- Parameters:
metadata
- the metadata to search for.- Returns:
- the identifier of the given metadata, or
null
if none. - Throws:
MetadataStoreException
- if the metadata object does not implement a metadata interface of the expected package, or if an error occurred while searching in the database.
-
search
final String search(String table, Set<String> columns, Map<String, Object> metadata, Statement stmt, SQLBuilder helper) throws SQLException, org.opengis.util.FactoryExceptionSearches for the given metadata in the database. If such metadata is found, then its identifier (primary key) is returned. Otherwise this method returnsnull
.- Parameters:
table
- the table where to search.columns
- the table columns as given bygetExistingColumns(String)
, ornull
.metadata
- a map view of the metadata to search for.stmt
- the statement to use for executing the query.helper
- an helper class for creating the SQL query.- Returns:
- the identifier of the given metadata, or
null
if none. - Throws:
SQLException
- if an error occurred while searching in the database.org.opengis.util.FactoryException
-
toStorableValue
Converts the given object to a value that can be stored in the database.- Throws:
org.opengis.util.FactoryException
- if an error occurred while using the geodetic database.
-
getExistingColumns
Returns the set of all columns in a table, or an empty set if none (nevernull
). Because each table should have at least the "ID" column, an empty set of columns will be understood as meaning that the table does not exist.This method returns a direct reference to the cached set. The returned set shall be modified in-place if new columns are added in the database table.
- Parameters:
table
- the name of the table for which to get the columns.- Returns:
- the set of columns, or an empty set if the table has not yet been created.
- Throws:
SQLException
- if an error occurred while querying the database.
-
lookup
Returns an implementation of the specified metadata interface filled with the data referenced by the specified identifier. Alternatively, this method can also return aCodeList
orEnum
element.- Type Parameters:
T
- the parameterized type of thetype
argument.- Parameters:
type
- the interface to implement (e.g.Citation
), or theControlledVocabulary
type (CodeList
or someEnum
).identifier
- the identifier of the record for the metadata entity to be created. This is usually the primary key of the record to search for.- Returns:
- an implementation of the required interface, or the code list element.
- Throws:
MetadataStoreException
- if a SQL query failed or if the metadata has not been found.
-
lookup
private Object lookup(Class<?> type, String identifier, boolean verify) throws MetadataStoreException Implementation of publiclookup(Class, String)
method.Deferred database access
This method may or may not query the database immediately, at implementation choice. It the database is not queried immediately, invalid identifiers may not be detected during this method invocation. Instead, an invalid identifier may be detected only when a getter method is invoked on the returned metadata object. In such case, anBackingStoreException
will be thrown at getter method invocation time.- Parameters:
type
- the interface to implement or theinvalid reference
ControlledVocabulary
identifier
- the identifier of the record for the metadata entity to be created.verify
- whether to check for record existence.- Returns:
- an implementation of the required interface, or the code list element.
- Throws:
MetadataStoreException
- if a SQL query failed or if the metadata has not been found.
-
getLookupInfo
Gets theLookupInfo
instance for call to thereadColumn(LookupInfo, Method, Dispatcher)
method. The call to those two methods must be in the same thread, and no other metadata object shall be queried between the two calls (unlessLookupInfo.setMetadataType(Class)
is invoked again).- Parameters:
type
- the interface class. This is mapped to the table name in the database.
-
readColumn
final Object readColumn(LookupInfo info, Method method, Dispatcher toSearch) throws SQLException, MetadataStoreException Invoked byMetadataProxy
for fetching an attribute value from a table. It the database table does not contains a column for the property, this method returnsnull
. Anull
value may also mean that the column exists but contains an SQLNULL
value.- Parameters:
info
- the interface type (together with cached information). This is mapped to the table name in the database.method
- the method invoked. This is mapped to the column name in the database.toSearch
- contains the identifier and preferred index of the record to search.- Returns:
- the value of the requested attribute, or
null
if none. - Throws:
SQLException
- if the SQL query failed.MetadataStoreException
- if a value was not found or cannot be converted to the expected type.
-
getCodeList
Returns the code of the given type and name. This method is defined for avoiding the compiler warning message when the actual class is unknown (it must have been checked dynamically by the caller however). -
specialize
private static <E> Collection<?> specialize(Collection<?> collection, Class<?> returnType, Class<E> elementType) Copies the given collection into the bestSet
implementation if possible, or returns the given collection unchanged otherwise.- Parameters:
collection
- the collection to copy.returnType
- the desired collection type.elementType
- the type of elements in the collection.- Returns:
- the collection of a specialized type if relevant.
-
warning
Reports a warning.- Parameters:
source
- the source class, eitherMetadataSource
orMetadataWriter
.method
- the method to report as the warning emitter.record
- the warning to report.
-
setWarningFilter
Sets a filter to be notified when a warning occurred while reading from or writing metadata. When a warning occurs, there is a choice:- If this metadata source has no warning filter, or if the filter returns
true
, then the warning is logged atLevel.WARNING
. - Otherwise the warning is not logged by this metadata source instance. The filter implementation is free to keep a reference to the given record, for example in order to display it in a graphical user interface.
- Parameters:
filter
- the filter to set, ornull
for removing the filter.- Returns:
- the previous filter, or
null
if none. - Since:
- 1.1
- If this metadata source has no warning filter, or if the filter returns
-
getWarningFilter
Returns the current warning filter.- Returns:
- the current filter, or
null
if none. - Since:
- 1.1
-
scheduleCloseTask
private void scheduleCloseTask()Schedules a task for closing the statements and the connection, if no such task is scheduled. -
closeExpired
final void closeExpired()Executed in a background thread for closing statements after their expiration time. This task will be given to the executor every time the first statement is recycled. -
closeQuietly
Closes the given resource without throwing exception. In case of failure while closing the resource, the message is logged but the process continue since we are not supposed to use the resource anymore. This method is invoked from methods that cannot throw a SQL exception. -
close
Closes the database connection used by this object.- Specified by:
close
in interfaceAutoCloseable
- Throws:
MetadataStoreException
- if an error occurred while closing the connection.
-