Java tutorial
/** * '$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 edu.lternet.pasta.dml; 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 edu.lternet.pasta.dml.database.ConnectionNotAvailableException; import edu.lternet.pasta.dml.database.DatabaseAdapter; import edu.lternet.pasta.dml.database.DatabaseConnectionPoolInterface; import edu.lternet.pasta.dml.database.DatabaseHandler; import edu.lternet.pasta.dml.database.HSQLAdapter; import edu.lternet.pasta.dml.database.OracleAdapter; import edu.lternet.pasta.dml.database.PostgresAdapter; import edu.lternet.pasta.dml.database.Query; import edu.lternet.pasta.dml.database.TableMonitor; import edu.lternet.pasta.dml.database.Union; import edu.lternet.pasta.dml.download.DownloadHandler; import edu.lternet.pasta.dml.download.DataStorageInterface; import edu.lternet.pasta.dml.download.EcogridEndPointInterface; import edu.lternet.pasta.dml.parser.Attribute; import edu.lternet.pasta.dml.parser.AttributeList; import edu.lternet.pasta.dml.parser.DataPackage; import edu.lternet.pasta.dml.parser.Entity; import edu.lternet.pasta.dml.parser.generic.DataPackageParserInterface; import edu.lternet.pasta.dml.parser.generic.Eml200DataPackageParser; import edu.lternet.pasta.dml.quality.QualityCheck; import edu.lternet.pasta.dml.quality.QualityReport; import edu.lternet.pasta.dml.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; } }