/**
* '$RCSfile: DataManager.java,v $'
*
* '$Author: leinfelder $'
* '$Date: 2008-02-28 23:40:53 $'
* '$Revision: 1.34 $'
*
* For Details: http://kepler.ecoinformatics.org
*
* Copyright (c) 2003 The Regents of the University of California.
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
* FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
* PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
* OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
package org.ecoinformatics.datamanager;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ecoinformatics.datamanager.database.ConnectionNotAvailableException;
import org.ecoinformatics.datamanager.database.DatabaseAdapter;
import org.ecoinformatics.datamanager.database.DatabaseConnectionPoolInterface;
import org.ecoinformatics.datamanager.database.DatabaseHandler;
import org.ecoinformatics.datamanager.database.HSQLAdapter;
import org.ecoinformatics.datamanager.database.OracleAdapter;
import org.ecoinformatics.datamanager.database.PostgresAdapter;
import org.ecoinformatics.datamanager.database.Query;
import org.ecoinformatics.datamanager.database.TableMonitor;
import org.ecoinformatics.datamanager.database.Union;
import org.ecoinformatics.datamanager.download.DownloadHandler;
import org.ecoinformatics.datamanager.download.DataStorageInterface;
import org.ecoinformatics.datamanager.download.EcogridEndPointInterface;
import org.ecoinformatics.datamanager.parser.Attribute;
import org.ecoinformatics.datamanager.parser.AttributeList;
import org.ecoinformatics.datamanager.parser.DataPackage;
import org.ecoinformatics.datamanager.parser.Entity;
import org.ecoinformatics.datamanager.parser.generic.DataPackageParserInterface;
import org.ecoinformatics.datamanager.parser.generic.Eml200DataPackageParser;
import org.ecoinformatics.datamanager.quality.QualityCheck;
import org.ecoinformatics.datamanager.quality.QualityReport;
import org.ecoinformatics.datamanager.quality.QualityCheck.Status;
/**
*
* The DataManager class is the controlling class for the library. It exposes
* the high-level API to the calling application.
*
* There are six use-cases that this library supports:
*
* 1. Parse the metadata to get at its entities and attributes.
* 2. Download a data table from a remote site, using the URL in the metadata.
* 3. Load a data table into the database table cache.
* 4. Query a data table with a SQL select statement.
* 5. Set an upper limit on the size of the database table cache.
* 6. Set an expiration policy on a table in the database table cache.
*
*/
public class DataManager {
/*
* Class fields
*/
public static Log log = LogFactory.getLog(DataManager.class);
/* Holds the singleton object for this class */
private static DataManager dataManager = null;
private static String databaseAdapterName = null;
private static DatabaseConnectionPoolInterface connectionPool = null;
// Constants
private static final String BLANKSTR = "";
private static final int MAXIMUM_NUMBER_TO_ACCESS_CONNECTIONPOOL = 10;
private static final int SLEEP_TIME = 2000;
/*
* Constructors
*/
/*
* This is singleton class, so constructor is private
*/
private DataManager(DatabaseConnectionPoolInterface connectionPool,
String databaseAdapterName)
{
DataManager.connectionPool = connectionPool;
DataManager.databaseAdapterName = databaseAdapterName;
}
/*
* Class methods
*/
/**
* Gets the singleton instance of this class.
*
* @return the single instance of the DataManager class.
*/
static public DataManager getInstance(
DatabaseConnectionPoolInterface connectionPool,
String databaseAdapterName) {
if (dataManager == null)
{
dataManager = new DataManager(connectionPool, databaseAdapterName);
}
else if (DataManager.databaseAdapterName != null &&
!DataManager.databaseAdapterName.equals(databaseAdapterName)
)
{
dataManager = new DataManager(connectionPool, databaseAdapterName);
}
return dataManager;
}
/*
* Gets DBConnection from connection pool. If no connection available, it will
* sleep and try again. If ceiling times reachs, null will return.
*
*/
public static Connection getConnection() throws SQLException
{
Connection connection = null;
int index = 0;
if (connectionPool == null)
{
throw new SQLException("The Connection Pool is null");
}
while (index <MAXIMUM_NUMBER_TO_ACCESS_CONNECTIONPOOL)
{
try
{
connection = connectionPool.getConnection();
break;
}
catch (ConnectionNotAvailableException cna)
{
try
{
Thread.sleep(SLEEP_TIME);
}
catch(Exception e)
{
log.error("Error in DataManager.getConnection(): " +
e.getMessage());
}
}
catch (SQLException sql)
{
log.error("Error in DataManager.getConnection(): " +
sql.getMessage());
}
index++;
}
return connection;
}
/**
* Returns checked out connection to connection pool.
*
* @param connection the Connection to be returned to the pool
*/
public static void returnConnection(Connection connection)
{
connectionPool.returnConnection(connection);
}
/**
* Get the value of the databaseAdapterName field.
*
* @return the value of the databaseAdapterName field
*/
public static String getDatabaseAdapterName() {
return databaseAdapterName;
}
/**
* Gets the object of the database connection pool
* @return the object of dababase connection pool
*/
public static DatabaseConnectionPoolInterface getDatabaseConnectionPool()
{
return connectionPool;
}
/*
* Instance methods
*/
/**
* Create a database view from one or more entities in an entity list.
*
* @param ANSISQL ANSI SQL string to create the view.
* @param entityList Array of entities whose table names and attribute
* names are used in creating the view.
* @return a boolean value indicating the success of the create view
* operation. True will be returned if successful, else false
* will be returned.
*/
public boolean createDataView(String ANSISQL, Entity[] entityList) {
boolean success = true;
return success;
}
/**
* Downloads all entities in a data package using the calling application's
* data storage interface. This allows the calling application to manage its
* data store in its own way. This version of the method downloads all
* entities in the entity list of the data package. This method implements
* Use Case #2.
*
* @param dataPackage the data package containing a list of entities
* @param endPointInfo which provides ecogrid endpoint information
* @param dataStorageList the destination (data storage) of the downloading
* @return a boolean value indicating the success of the download operation.
* true if successful, else false.
*/
public boolean downloadData(DataPackage dataPackage, EcogridEndPointInterface endPointInfo,
DataStorageInterface[] dataStorageList) {
boolean success = true;
Entity[] entities = dataPackage.getEntityList();
for (int i = 0; i < entities.length; i++) {
Entity entity = entities[i];
success = downloadData(entity, endPointInfo, dataStorageList) && success;
}
return success;
}
/**
* Downloads a single entity using the calling application's data storage
* interface. This allows the calling application to manage its data store
* in its own way. This method implements Use Case #2.
*
* This version of the method sets preserveFormat to false. This is
* the Data Manager Library's original default behavior: gzip, zip,
* or tar files are expanded when downloaded.
*
* @param entity the entity whose data is to be downloaded
* @param endPointInfo which provides ecogrid endpoint information
* @param dataStorageList the destination (data storage) of the downloading
* @return a boolean value indicating the success of the download operation.
* true if successful, else false.
*/
public boolean downloadData(Entity entity, EcogridEndPointInterface endPointInfo,
DataStorageInterface[] dataStorageList) {
boolean preserveFormat = false;
return downloadData(entity, endPointInfo, dataStorageList, preserveFormat);
}
/**
* Downloads a single entity using the calling application's data storage
* interface. This allows the calling application to manage its data store
* in its own way. This method implements Use Case #2.
*
* This newer version of the method accepts a boolean value, preserveFormat.
* Setting preserveFormat to false invokes the Data Manager Library's
* original default behavior: an object with a compressionMethod of 'gzip'
* or 'zip' or an encodingMethod of 'tar' is expanded when downloaded.
* However, when set to true, the object is downloaded with its original format
* preserved.
*
* @param entity the entity whose data is to be downloaded
* @param endPointInfo which provides ecogrid endpoint information
* @param dataStorageList the destination (data storage) of the downloading
* @param preserveFormat when set to true, do not unzip or un-tar the entity
* @return a boolean value indicating the success of the download operation.
* true if successful, else false.
*/
public boolean downloadData(Entity entity, EcogridEndPointInterface endPointInfo,
DataStorageInterface[] dataStorageList, boolean preserveFormat) {
log.debug(String.format("***** Downloading data for: %s, entity: %s\n", entity.getPackageId(), entity.getName()));
DownloadHandler downloadHandler = entity.getDownloadHandler(endPointInfo, preserveFormat);
boolean success = false;
if (downloadHandler != null) {
try {
success = downloadHandler.download(dataStorageList);
}
catch (Exception e) {
log.error("Error downloading entity name '" + entity.getName() + "': " + e.getMessage());
success = false;
}
}
return success;
}
/**
* Downloads data from an input stream using the calling application's data
* storage interface. This allows the calling application to manage its
* data store in its own way. The metadata input stream first needs to be
* parsed and a data package created from it. Then, all entities in the data
* package are downloaded. This method implements Use Case #2.
*
* @param metadataInputStream an input stream to the metadata.
* @param endPointInfo which provides ecogrid endpoint information
* @param dataStorageList the destination (data storage) of the downloading
* @return a boolean value indicating the success of the download operation.
* true if successful, else false.
*/
public boolean downloadData(InputStream metadataInputStream, EcogridEndPointInterface endPointInfo,
DataStorageInterface[] dataStorageList)
throws Exception {
boolean success = false;
DataPackage dataPackage = parseMetadata(metadataInputStream);
if (dataPackage != null) {
success = downloadData(dataPackage, endPointInfo, dataStorageList);
}
return success;
}
/**
* Drops all tables in a data package. This is simply a pass-through to the
* DatabaseHandler class.
*
* @param dataPackage the DataPackage object whose tables are to be dropped
* @return true if successful, else false
* @throws ClassNotFoundException
* @throws SQLException
* @throws Exception
*/
public boolean dropTables(DataPackage dataPackage)
throws ClassNotFoundException, SQLException, Exception {
boolean success;
DatabaseHandler databaseHandler = new DatabaseHandler(databaseAdapterName);
success = databaseHandler.dropTables(dataPackage);
return success;
}
/**
* Drops all tables in a data package based on a packageId value. This is
* simply a pass-through to the DatabaseHandler class.
*
* @param packageId the packageId associated with tables are to be dropped
* @return true if successful, else false
* @throws ClassNotFoundException
* @throws SQLException
* @throws Exception
*/
public boolean dropTables(String packageId)
throws ClassNotFoundException, SQLException, Exception {
boolean success;
DatabaseHandler databaseHandler = new DatabaseHandler(databaseAdapterName);
success = databaseHandler.dropTables(packageId);
return success;
}
/**
* Creates each table described in the datapackage
* @param dataPackage
* @return boolean indicating success or failure of the operation
* @throws SQLException
* @throws Exception
*/
public boolean createTables(DataPackage dataPackage)
throws SQLException, Exception {
boolean success;
DatabaseHandler databaseHandler = new DatabaseHandler(databaseAdapterName);
success = databaseHandler.generateTables(dataPackage);
return success;
}
/**
* Gets the database field name for a given entity attribute. First, we
* ask the Attribute object for its dbFieldName value. If it doesn't know,
* we check to see if it persists in the database.
*
* @param entity the Entity that holds this attribute
* @param attribute the Attribute whose database field name we want to get
* @return dbFieldName the database field name for this attribute, or null
* if no database field name can be found
*/
public static String getDBFieldName(Entity entity, Attribute attribute)
throws SQLException {
String dbFieldName = null;
// First, access the dbFieldName directly from the attribute object
dbFieldName = attribute.getDBFieldName();
/*
* If the attribute doesn't contain a value, get it from the database
* field names stored in the entity's database table.
*/
if (dbFieldName == null || dbFieldName.trim().equals(BLANKSTR)) {
if (entity != null && attribute != null) {
Attribute[] attributeArray = entity.getAttributes();
String packageID = entity.getPackageId();
String entityName = entity.getName();
String[] dbFieldNames = getDBFieldNames(packageID, entityName);
if (attributeArray.length == dbFieldNames.length) {
for (int i = 0; i < attributeArray.length; i++) {
Attribute arrayAttribute = attributeArray[i];
if (attribute.equals(arrayAttribute)) {
dbFieldName = dbFieldNames[i];
}
}
}
}
}
return dbFieldName;
}
/**
* Gets a list of database field names for the specified packageID and entity
* name. This is a pass-through to the same method in the TableMonitor class.
*
* @param packageID the packageID for this entity
* @param entityName the entity name
* @return a String array holding the field names for this entity, or null
* if there was no match for this packageID and entity name in the
* database.
* @throws SQLException
*/
public static String[] getDBFieldNames(String packageID, String entityName)
throws SQLException {
String[] dbFieldNames = null;
DatabaseAdapter dbAdapter = getDatabaseAdapterObject(databaseAdapterName);
TableMonitor tableMonitor = new TableMonitor(dbAdapter);
dbFieldNames = tableMonitor.getDBFieldNames(packageID, entityName);
return dbFieldNames;
}
/**
* Gets the database table name for a specified packageID and entity name.
* This is a pass-through to the same method in the TableMonitor class.
*
* @param packageID the packageID for this entity
* @param entityName the entity name
* @return dbTableName the database table name for this entity, or null if
* no match to the packageID and entity name is found
* @throws SQLException
*/
public static String getDBTableName(String packageID, String entityName)
throws SQLException {
String dbTableName = null;
DatabaseAdapter dbAdapter = getDatabaseAdapterObject(databaseAdapterName);
TableMonitor tableMonitor = new TableMonitor(dbAdapter);
dbTableName = tableMonitor.getDBTableName(packageID, entityName);
return dbTableName;
}
/**
* Gets the database table name for a specified Entity.
* This is an alternative signature that uses an Entity object instead of
* string parameters. First we ask the Entity to tell us its table name,
* but if it doesn't know, we check to see whether the table name for this
* entity is persistent in the database.
*
* @param entity the Entity object whose table name is being determined
* @return dbTableName the database table name for this entity, or null if
* no match to the packageID and entity name is found
* @throws SQLException
*/
public static String getDBTableName(Entity entity) throws SQLException {
String dbTableName = null;
// First, try to get the dbTableName directly from the Entity object
if (entity != null) {
dbTableName = entity.getDBTableName();
/* If the entity doesn't know its dbTableName value, use the entity's
* packageID and name fields to query the database for the entity's
* table_name field value.
*/
if (dbTableName == null || dbTableName.trim().equals(BLANKSTR)) {
String packageID = entity.getPackageId();
String entityName = entity.getName();
dbTableName = DataManager.getDBTableName(packageID, entityName);
}
}
return dbTableName;
}
/**
* Loads all entities in a data package to the database table cache. This
* method implements Use Case #3.
*
* @param dataPackage the data package containing a list of entities whose
* data is to be loaded into the database table cache.
* @param endPointInfo which provides ecogrid endpoint information
* @return a boolean value indicating the success of the load-data operation.
* true if successful, else false.
*/
public boolean loadDataToDB(DataPackage dataPackage, EcogridEndPointInterface endPointInfo)
throws ClassNotFoundException, SQLException, Exception {
boolean success = true;
Entity[] entities = dataPackage.getEntityList();
for (int i = 0; i < entities.length; i++) {
success = loadDataToDB(entities[i],endPointInfo) && success;
}
return success;
}
/**
* Loads data from a single entity into the database table cache.
* This method implements Use Case #3.
*
* @param entity the entity whose data is to be loaded into the database
* table cache.
* @param endPointInfo which provides ecogrid endpoint information
* @return a boolean value indicating the success of the load-data operation.
* true if successful, else false.
*/
public boolean loadDataToDB(Entity entity, EcogridEndPointInterface endPointInfo)
throws ClassNotFoundException, SQLException, Exception {
boolean success = false;
log.debug(String.format("***** Loading data to DB for: %s, entity: %s\n", entity.getPackageId(), entity.getName()));
// Initialize the dataLoadQualityCheck
String qualityCheckIdentifier = "dataLoadStatus";
QualityCheck qualityCheckTemplate = QualityReport.getQualityCheckTemplate(qualityCheckIdentifier);
QualityCheck dataLoadQualityCheck = new QualityCheck(qualityCheckIdentifier, qualityCheckTemplate);
/*
* otherEntity is allowed to optionally omit the attributeList element.
* If this is an otherEntity and its attributeList is null, or it is
* non-null but it contains an empty attribute array, return success.
*/
if ((entity != null) && (entity.isOtherEntity())) {
AttributeList attributeList = entity.getAttributeList();
if (attributeList == null) {
success = true;
}
else {
Attribute[] attributes = attributeList.getAttributes();
if (attributes == null) {
success = true;
}
}
if (success) {
// Create an informational quality check stating that the data load
// was not attempted for this otherEntity entity.
if (QualityCheck.shouldRunQualityCheck(entity, dataLoadQualityCheck)) {
dataLoadQualityCheck.setFound(
"Data loading was not attempted for this 'otherEntity' " +
"because no attribute list was found in the EML");
dataLoadQualityCheck.setExplanation(
"In EML, a data entity of type 'otherEntity' is not required " +
"to document an attribute list");
entity.addQualityCheck(dataLoadQualityCheck);
}
}
}
/*
* Do not attempt to load data into a database table if the entity
* does not have a distribution online and has either distribution
* offline or inline.
*/
else if ((entity != null) &&
!entity.hasDistributionOnline() &&
(entity.hasDistributionOffline() ||
entity.hasDistributionInline()
)
) {
success = true;
if (QualityCheck.shouldRunQualityCheck(entity, dataLoadQualityCheck)) {
dataLoadQualityCheck.setFound(
"Data loading was not attempted for this entity " +
"because its distribution is 'inline' or 'offline'");
dataLoadQualityCheck.setExplanation(
"Unable to process data entities with distribution " +
"set to 'inline' or 'offline'");
entity.addQualityCheck(dataLoadQualityCheck);
}
}
else {
try {
DatabaseHandler databaseHandler =
new DatabaseHandler(databaseAdapterName);
// First, generate a table for the entity
success = databaseHandler.generateTable(entity);
// If we have a table, then load the data for the entity.
if (success) {
success = databaseHandler.loadDataToDB(entity, endPointInfo);
// If the data could not be loaded to the database, drop the table.
if (!success) {
databaseHandler.dropTable(entity);
}
}
}
catch (SQLException e) {
success = false;
}
finally {
}
}
return success;
}
/**
* Loads all entities in a data package to the database table cache. This
* version of the method is passed a metadata input stream that needs
* to be parsed. Then, all entities in the data package are loaded to the
* database table cache. This method implements Use Case #3.
*
* @param metadataInputStream the metadata input stream to be parsed into
* a DataPackage object.
* @param endPointInfo which provides ecogrid endpoint information
* @return a boolean value indicating the success of the load-data operation.
* true if successful, else false.
*/
public boolean loadDataToDB(InputStream metadataInputStream, EcogridEndPointInterface endPointInfo)
throws Exception {
boolean success = false;
DataPackage dataPackage = parseMetadata(metadataInputStream);
if (dataPackage != null) {
success = loadDataToDB(dataPackage, endPointInfo);
}
return success;
}
/**
* Parses metadata using the appropriate parser object. The return value is
* a DataPackage object containing the parsed metadata. This method
* implements Use Case #1.
*
* @param metadataInputStream an input stream to the metadata to be parsed.
* @return a DataPackage object containing the parsed metadata
*/
public DataPackage parseMetadata(InputStream metadataInputStream)
throws Exception {
DataPackage dataPackage = null;
DataPackageParserInterface parser = new Eml200DataPackageParser();
parser.parse(metadataInputStream);
dataPackage = parser.getDataPackage();
dataPackageQuality(dataPackage);
return dataPackage;
}
/**
* Parses metadata using the passed parser parameter. The return value is
* a DataPackage object containing the parsed metadata. This method
* implements Use Case #1.
*
* @param metadataInputStream an input stream to the metadata to be parsed.
* @param genericParser the appropriate parser implementation for the metadataInputStream
* @return a DataPackage object containing the parsed metadata
*
* @throws Exception
*/
public DataPackage parseMetadata(InputStream metadataInputStream, DataPackageParserInterface genericParser)
throws Exception {
DataPackage dataPackage = null;
genericParser.parse(metadataInputStream);
dataPackage = genericParser.getDataPackage();
dataPackageQuality(dataPackage);
return dataPackage;
}
/*
* If quality reporting is enabled, runs quality checks on the
* data package and stores the results in its QualityReport
* object.
*/
private void dataPackageQuality(DataPackage dataPackage) {
// Initialize the duplicateEntityName quality check
String duplicateEntityIdentifier = "duplicateEntityName";
QualityCheck duplicateEntityTemplate = QualityReport.getQualityCheckTemplate(duplicateEntityIdentifier);
QualityCheck duplicateEntityQualityCheck =
new QualityCheck(duplicateEntityIdentifier, duplicateEntityTemplate);
if (QualityCheck.shouldRunQualityCheck(dataPackage, duplicateEntityQualityCheck)) {
String duplicateName = dataPackage.findDuplicateEntityName();
boolean hasDuplicate = (duplicateName != null);
if (hasDuplicate) {
duplicateEntityQualityCheck.setFound("Found duplicate entity name: " +
duplicateName);
duplicateEntityQualityCheck.setFailedStatus();
}
else {
duplicateEntityQualityCheck.setFound("No duplicates found");
duplicateEntityQualityCheck.setStatus(Status.valid);
}
dataPackage.addDatasetQualityCheck(duplicateEntityQualityCheck);
}
}
/**
* Runs a database query on one or more data packages. This method
* implements Use Case #4.
*
* @param query A Query java object hold query information.
* @param packages The data packages holding the entities to be queried.
* Metadata about the data types of the attributes being
* queried is contained in these data packages.
* @return A ResultSet object holding the query results.
*/
public ResultSet selectData(Query query, DataPackage[] packages)
throws ClassNotFoundException, SQLException, Exception {
DatabaseHandler databaseHandler;
ResultSet resultSet = null;
try
{
databaseHandler = new DatabaseHandler(databaseAdapterName);
String ANSISQL = query.toSQLString();
resultSet = databaseHandler.selectData(ANSISQL, packages);
}
finally
{}
return resultSet;
}
/**
* Runs a database query on one or more metadata input streams. Each of the
* metadata input streams needs to first be parsed, creating a list of data
* packages. The data packages contain entities, and the entities hold metadata
* about the data types of the attributes being queried. This method
* implements Use Case #4.
*
* @param query A Query java object hold query information.
* @param emlInputStreams An array of input streams that need to be parsed
* into a list of data packages. The data packages hold the
* lists of entities to be queried. Metadata about the data
* types of the attributes in the select statement is
* contained in these data packages.
* @return A ResultSet object holding the query results.
*/
public ResultSet selectData(Query query, InputStream[] emlInputStreams)
throws Exception {
DataPackage[] packages = new DataPackage[emlInputStreams.length];
ResultSet resultSet = null;
for (int i = 0; i < emlInputStreams.length; i++) {
DataPackage dataPackage = parseMetadata(emlInputStreams[i]);
packages[i] = dataPackage;
}
resultSet = selectData(query, packages);
return resultSet;
}
public ResultSet selectData(Union union, DataPackage[] packages)
throws ClassNotFoundException, SQLException, Exception {
DatabaseHandler databaseHandler;
ResultSet resultSet = null;
try {
databaseHandler = new DatabaseHandler(databaseAdapterName);
String ANSISQL = union.toSQLString();
resultSet = databaseHandler.selectData(ANSISQL, packages);
} finally {}
return resultSet;
}
/**
* Runs a database query on a view. The view must already exist in the
* database (see createDataView() method).
*
* @param ANSISQL A string holding the ANSI SQL selection syntax.
* @return A ResultSet object holding the query results.
*/
public ResultSet selectDataFromView(String ANSISQL) {
ResultSet resultSet = null;
return resultSet;
}
/**
* Set the String value of the databaseAdapterName field.
*
* This method should probably throw an exception if the value does not
* match any members of the recognized set of database adapter names.
*
* @param databaseAdapterName
*/
public void setDatabaseAdapterName(String databaseAdapterName) {
DataManager.databaseAdapterName = databaseAdapterName;
}
/**
* Sets an upper limit on the size of the database table cache. If the limit
* is about to be exceeded, the TableMonitor will attempt to free up space
* by deleting old tables from the table cache. This method implements
* Use Case #5.
*
* @param size The upper limit, in MB, on the size of the database table
* cache.
*/
public void setDatabaseSize(int size) throws SQLException, ClassNotFoundException {
try
{
DatabaseAdapter dbAdapter = getDatabaseAdapterObject(databaseAdapterName);
TableMonitor tableMonitor = new TableMonitor(dbAdapter);
tableMonitor.setDBSize(size);
}
finally
{}
}
/**
* Sets the expiration policy on a table in the database table cache. The
* policy is an enumerated integer value indicating whether this table can
* be expired from the cache. (The precise meaning of these values is yet to
* be determined.) This method implements Use Case #6.
*
* @param tableName the name of the table whose expiration policy is being
* set
* @param policy an enumerated integer value indicating whether the table
* should be expired from the datbase table cache. (The
* precise meaning of this value is yet to be determined.)
*/
public void setTableExpirationPolicy(String tableName, int policy)
throws SQLException, ClassNotFoundException {
try
{
DatabaseAdapter dbAdapter = getDatabaseAdapterObject(databaseAdapterName);
TableMonitor tableMonitor = new TableMonitor(dbAdapter);
tableMonitor.setTableExpirationPolicy(tableName, policy);
}
finally
{}
}
/**
* Constructs and returns a DatabaseAdapter object based on a given database
* adapter name.
*
* @param dbAdapterName Database adapter name, a string. It should match
* one of the constants in the DatabaseAdapter class,
* e.g. DatabaseAdapter.POSTGRES_ADAPTER. If no match
* is made, returns null.
*/
public static DatabaseAdapter getDatabaseAdapterObject(String dbAdapterName)
{
if (dbAdapterName == null)
{
return null;
}
if (dbAdapterName.equals(DatabaseAdapter.POSTGRES_ADAPTER)) {
PostgresAdapter databaseAdapter = new PostgresAdapter();
return databaseAdapter;
}
else if (dbAdapterName.equals(DatabaseAdapter.HSQL_ADAPTER)) {
HSQLAdapter databaseAdapter = new HSQLAdapter();
return databaseAdapter;
}
else if (dbAdapterName.equals(DatabaseAdapter.ORACLE_ADAPTER)) {
OracleAdapter databaseAdapter = new OracleAdapter();
return databaseAdapter;
}
return null;
}
}