APIdia Launch Partner
Top Description Inners Fields Constructors Methods
io.github.spannm.jackcess.util

public abstract Class CustomLinkResolver

extends Object
implements LinkResolver
Class Inheritance
All Implemented Interfaces
io.github.spannm.jackcess.util.LinkResolver
Imports
io.github.spannm.jackcess.Database, .Database.FileFormat, .Table, io.github.spannm.jackcess.impl.ByteUtil, .DatabaseImpl, .TableImpl, java.io.Closeable, .IOException, java.nio.channels.FileChannel, java.nio.file.Files, .Path, .Paths, java.util.Random

Utility base implementation of LinkResolver which facilitates loading linked tables from files which are not access databases. The LinkResolver API ultimately presents linked table information to the primary database using the jackcess Database and Table classes. In order to consume linked tables in non-mdb files, they need to somehow be coerced into the appropriate form. The approach taken by this utility is to make it easy to copy the external tables into a temporary mdb file for consumption by the primary database.

The primary features of this utility:

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
CustomLinkResolver.TempDatabaseImpl

Subclass of DatabaseImpl which allows us to load tables "on demand" as well as delete the temporary db on close.

Field Summary

Modifier and TypeField and Description
private static final Random
public static final Database.FileFormat
DEFAULT_FORMAT

the default file format used for temp dbs

public static final boolean
DEFAULT_IN_MEMORY

temp dbs default to the filesystem, not in memory

public static final Path
DEFAULT_TEMP_DIR

temp dbs end up in the system temp dir by default

private final Database.FileFormat
private final boolean
private final Path
private static final String
private static final String

Constructor Summary

AccessConstructor and Description
protected
CustomLinkResolver()

Creates a CustomLinkResolver using the default behavior for creating temp dbs, see DEFAULT_FORMAT, DEFAULT_IN_MEMORY and DEFAULT_TEMP_DIR.

protected
CustomLinkResolver(Database.FileFormat
the default format for the temp db
defaultFormat
,
boolean
whether or not the temp db should be entirely in memory by default (while this will be faster, it should only be used if table data is expected to fit entirely in memory)
defaultInMemory
,
Path
the default temp dir for a file based temp db (null for the system defaqult temp directory)
defaultTempDir
)

Creates a CustomLinkResolver with the given default behavior for creating temp dbs.

Method Summary

Modifier and TypeMethod and Description
private static void
closeCustomFile(Object customFile)

protected Database

Returns:

the temp db for holding the linked table info
createTempDb
(Object
custom file state returned from loadCustomFile
customFile
,
Database.FileFormat
the access format for the temp db
format
,
boolean
whether or not the temp db should be entirely in memory (while this will be faster, it should only be used if table data is expected to fit entirely in memory)
inMemory
,
Path
the temp dir for a file based temp db (null for the system default temp directory)
tempDir
,
boolean readOnly)

Creates a temporary database for holding the table data from linkeeFileName.

private static void
protected Database.FileFormat
protected Path
protected boolean
protected abstract Object

Returns:

non-null if linkeeFileName should be treated as a custom file (using a temp db) or null if it should be treated as a normal access db.
loadCustomFile
(Database
the primary database in which the link is defined
linkerDb
,
String
the name of the linked file
linkeeFileName
)

Called by resolveLinkedDatabase to determine whether the linkeeFileName should be treated as a custom file (thus utiliziing a temp db) or a normal access db (loaded via the default behavior).

protected abstract boolean

Returns:

true if the table was available in the linked file, false otherwise
loadCustomTable
(Database
the temp db instance which should be populated with the relevant table info for the given tableName
tempDb
,
Object
custom file state returned from loadCustomFile
customFile
,
String
the name of the table which is requested from the linked file
tableName
)

Called by an instance of a temp db when a missing table is first requested.

public Database
resolveLinkedDatabase(Database linkerDb, String linkeeFileName)

Implements io.github.spannm.jackcess.util.LinkResolver.resolveLinkedDatabase.

Custom implementation is:

// attempt to load the linkeeFileName as a custom file
Object customFile = loadCustomFile(linkerDb, linkeeFileName);

if (customFile != null) {
    // this is a custom file, create and return relevant temp db
    return createTempDb(customFile, getDefaultFormat(), isDefaultInMemory(),
        getDefaultTempDirectory());
}

// not a custom file, load using the default behavior
return LinkResolver.DEFAULT.resolveLinkedDatabase(linkerDb, linkeeFileName);
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

DB_IDback to summary
private static final Random DB_ID
DEFAULT_FORMATback to summary
public static final Database.FileFormat DEFAULT_FORMAT

the default file format used for temp dbs

DEFAULT_IN_MEMORYback to summary
public static final boolean DEFAULT_IN_MEMORY

temp dbs default to the filesystem, not in memory

DEFAULT_TEMP_DIRback to summary
public static final Path DEFAULT_TEMP_DIR

temp dbs end up in the system temp dir by default

defaultFormatback to summary
private final Database.FileFormat defaultFormat
defaultInMemoryback to summary
private final boolean defaultInMemory
defaultTempDirback to summary
private final Path defaultTempDir
FILE_DB_PREFIXback to summary
private static final String FILE_DB_PREFIX
MEM_DB_PREFIXback to summary
private static final String MEM_DB_PREFIX

Constructor Detail

CustomLinkResolverback to summary
protected CustomLinkResolver()

Creates a CustomLinkResolver using the default behavior for creating temp dbs, see DEFAULT_FORMAT, DEFAULT_IN_MEMORY and DEFAULT_TEMP_DIR.

CustomLinkResolverback to summary
protected CustomLinkResolver(Database.FileFormat defaultFormat, boolean defaultInMemory, Path defaultTempDir)

Creates a CustomLinkResolver with the given default behavior for creating temp dbs.

Parameters
defaultFormat:Database.FileFormat

the default format for the temp db

defaultInMemory:boolean

whether or not the temp db should be entirely in memory by default (while this will be faster, it should only be used if table data is expected to fit entirely in memory)

defaultTempDir:Path

the default temp dir for a file based temp db (null for the system defaqult temp directory)

Method Detail

closeCustomFileback to summary
private static void closeCustomFile(Object customFile)
createTempDbback to summary
protected Database createTempDb(Object customFile, Database.FileFormat format, boolean inMemory, Path tempDir, boolean readOnly) throws IOException

Creates a temporary database for holding the table data from linkeeFileName.

Parameters
customFile:Object

custom file state returned from loadCustomFile

format:Database.FileFormat

the access format for the temp db

inMemory:boolean

whether or not the temp db should be entirely in memory (while this will be faster, it should only be used if table data is expected to fit entirely in memory)

tempDir:Path

the temp dir for a file based temp db (null for the system default temp directory)

Returns:Database

the temp db for holding the linked table info

Annotations
@SuppressWarnings:PMD.UseTryWithResources
deleteDbFileback to summary
private static void deleteDbFile(Path dbFile)
getDefaultFormatback to summary
protected Database.FileFormat getDefaultFormat()
getDefaultTempDirectoryback to summary
protected Path getDefaultTempDirectory()
isDefaultInMemoryback to summary
protected boolean isDefaultInMemory()
loadCustomFileback to summary
protected abstract Object loadCustomFile(Database linkerDb, String linkeeFileName)

Called by resolveLinkedDatabase to determine whether the linkeeFileName should be treated as a custom file (thus utiliziing a temp db) or a normal access db (loaded via the default behavior). Loads any state necessary for subsequently loading data from linkeeFileName.

The returned custom file state object will be maintained with the temp db and passed to loadCustomTable whenever a new table needs to be loaded. Also, if this object is Closeable, it will be closed with the temp db.

Parameters
linkerDb:Database

the primary database in which the link is defined

linkeeFileName:String

the name of the linked file

Returns:Object

non-null if linkeeFileName should be treated as a custom file (using a temp db) or null if it should be treated as a normal access db.

loadCustomTableback to summary
protected abstract boolean loadCustomTable(Database tempDb, Object customFile, String tableName) throws IOException

Called by an instance of a temp db when a missing table is first requested.

Parameters
tempDb:Database

the temp db instance which should be populated with the relevant table info for the given tableName

customFile:Object

custom file state returned from loadCustomFile

tableName:String

the name of the table which is requested from the linked file

Returns:boolean

true if the table was available in the linked file, false otherwise

resolveLinkedDatabaseback to summary
public Database resolveLinkedDatabase(Database linkerDb, String linkeeFileName) throws IOException

Implements io.github.spannm.jackcess.util.LinkResolver.resolveLinkedDatabase.

Custom implementation is:

// attempt to load the linkeeFileName as a custom file
Object customFile = loadCustomFile(linkerDb, linkeeFileName);

if (customFile != null) {
    // this is a custom file, create and return relevant temp db
    return createTempDb(customFile, getDefaultFormat(), isDefaultInMemory(),
        getDefaultTempDirectory());
}

// not a custom file, load using the default behavior
return LinkResolver.DEFAULT.resolveLinkedDatabase(linkerDb, linkeeFileName);
The fallback behavior denies automatic linked database resolution. The loadCustomFile implementation is application-provided and is responsible for validating its own input. Override this method and explicitly delegate to LinkResolver#UNRESTRICTED only when linked database paths come from a trusted source.
Annotations
@Override
See Also
loadCustomFile, createTempDb, LinkResolver#DEFAULT, LinkResolver#UNRESTRICTED
io.github.spannm.jackcess.util back to summary

private Class CustomLinkResolver.TempDatabaseImpl

extends DatabaseImpl
Class Inheritance

Subclass of DatabaseImpl which allows us to load tables "on demand" as well as delete the temporary db on close.

Field Summary

Modifier and TypeField and Description
private final Object
private final CustomLinkResolver
Inherited from io.github.spannm.jackcess.impl.DatabaseImpl:
DEFAULT_RESOURCE_PATHHIDDEN_OBJECT_FLAGRO_CHANNEL_OPTSRW_CHANNEL_OPTSRWC_CHANNEL_OPTS

Constructor Summary

AccessConstructor and Description
protected
TempDatabaseImpl(CustomLinkResolver resolver, Object customFile, Path file, FileChannel channel, Database.FileFormat fileFormat, boolean readOnly)

Method Summary

Modifier and TypeMethod and Description
public void
close()

Overrides io.github.spannm.jackcess.impl.DatabaseImpl.close.

Implements io.github.spannm.jackcess.Database.close.

Close the database file (and any linked databases).

protected TableImpl
getTable(String name, boolean includeSystemTables)

Overrides io.github.spannm.jackcess.impl.DatabaseImpl.getTable.

Returns the table, or null if it doesn't exist.

pack-priv static FileChannel
Inherited from io.github.spannm.jackcess.impl.DatabaseImpl:
clearTableCachecreatecreateDateFormatcreateLinkedTablecreateTablecreateTableflushgetAccessControlEntriesgetCharsetgetColumnOrdergetColumnValidatorFactorygetDatabasePasswordgetDatabasePropertiesgetDateTimeFactorygetDateTimeTypegetDefaultAllowAutoNumberInsertgetDefaultCharsetgetDefaultCodePagegetDefaultColumnOrdergetDefaultDateTimeTypegetDefaultEnforceForeignKeysgetDefaultEvaluateExpressionsgetDefaultSortOrdergetDefaultTimeZonegetDefaultWriteBrokenIndexgetErrorHandlergetEvalConfiggetFilegetFileFormatgetFileFormatDetailsgetFormatgetLinkedDatabasesgetLinkResolvergetNamegetPageChannelgetPasswordMaskgetPathgetPropertiesForObjectgetQueriesgetRelationshipsgetRelationshipsgetRelationshipsgetRelationshipsgetResourceAsStreamgetSummaryPropertiesgetSystemCataloggetSystemComplexColumnsgetSystemRelationshipsgetSystemTablegetSystemTableNamesgetTablegetTablegetTableMetaDatagetTableNamesgetTimeZonegetUserDefinedPropertiesgetZoneIdisAllowAutoNumberInsertisEnforceForeignKeysisEvaluateExpressionsisLinkedTableisReadOnlyisWriteBrokenIndexiteratoriteratornewIterablenewTableMetaDataIterableopenreadPropertiessetAllowAutoNumberInsertsetCharsetsetColumnOrdersetColumnValidatorFactorysetDateTimeTypesetEnforceForeignKeyssetErrorHandlersetEvaluateExpressionssetLinkResolversetTimeZonesetWriteBrokenIndexsetZoneIdtoLookupNametoStringtransferDatabasevalidateIdentifierNamevalidateNewTableName

Field Detail

customFileback to summary
private final Object customFile
resolverback to summary
private final CustomLinkResolver resolver

Constructor Detail

TempDatabaseImplback to summary
protected TempDatabaseImpl(CustomLinkResolver resolver, Object customFile, Path file, FileChannel channel, Database.FileFormat fileFormat, boolean readOnly) throws IOException

Method Detail

closeback to summary
public void close() throws IOException

Overrides io.github.spannm.jackcess.impl.DatabaseImpl.close.

Implements io.github.spannm.jackcess.Database.close.

Doc from io.github.spannm.jackcess.Database.close.

Close the database file (and any linked databases). A Database must be closed after use or changes could be lost and the Database file corrupted. A Database instance should be treated like any other external resource which would be closed in a finally block (e.g. an OutputStream or jdbc Connection).

Annotations
@Override
Exceptions
IOException:

Doc from java.io.Closeable.close.

if an I/O error occurs

getTableback to summary
protected TableImpl getTable(String name, boolean includeSystemTables) throws IOException

Overrides io.github.spannm.jackcess.impl.DatabaseImpl.getTable.

Doc from io.github.spannm.jackcess.impl.DatabaseImpl.getTable.

Returns the table, or null if it doesn't exist.

Annotations
@Override
initDbChannelback to summary
pack-priv static FileChannel initDbChannel(FileChannel channel, Database.FileFormat format) throws IOException