All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.org.jafer.databeans.DatabeanManager Maven / Gradle / Ivy

/**
 * JAFER Toolkit Project.
 * Copyright (C) 2002, JAFER Toolkit Project, Oxford University.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

/**
 *  Title: JAFER Toolkit
 *  Description:
 *  Copyright: Copyright (c) 2001
 *  Company: Oxford University
 *
 *@author     Antony Corfield; Matthew Dovey; Colin Tatham
 *@version    1.0
 */

package org.jafer.databeans;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.logging.Logger;

import org.jafer.exception.JaferException;
import org.jafer.interfaces.Cache;
import org.jafer.interfaces.Databean;
import org.jafer.interfaces.DatabeanFactory;
import org.jafer.interfaces.Present;
import org.jafer.interfaces.Search;
import org.jafer.query.JaferQuery;
import org.jafer.record.CacheFactory;
import org.jafer.record.Field;
import org.jafer.record.RecordException;
import org.jafer.util.xml.DOMFactory;
import org.w3c.dom.Node;

/**
 * This inner class represents a thread that performs a search on a Jafer Client
 * (AbstractClient). It is configured and utilised by the DataBeanManager in
 * order to facilitate parallel searches.
 */

class ActiveBean extends java.lang.Thread
{

    /**
     * Stores a reference to a flag that indicates that the thread should
     * terminate and prefilling of the cache should stop if it has not yet
     * completed
     */
    private boolean stopActiveBeanSearch = false;

    /**
     * Stores a reference to whether the search is still executing.
     */
    private boolean stillSearching = false;

    /**
     * Stores a reference to whether pre filling of the caching is enabled or
     * not. Enabled as default.
     */
    private boolean autoPopulateCache = true;

    /**
     * Stores a reference to record schema to use when preopoulating the cache
     */
    private String cacheRecordSchema = null;

    /**
     * Stores a reference to the offset this ActiveBean starts at in the super
     * result set of all the ActiveBeans
     */
    private int startOffset;

    /**
     * Stores a reference to the offset this ActiveBean ends at in the super
     * result set of all the ActiveBeans
     */
    private int endOffset;

    /**
     * Stores a reference to the bean that this ActiveBean uses to perform
     * searches and to retrieve results from. It must implement the Search and
     * Present interfaces.
     */
    private Databean databean;

    /**
     * Stores a reference to query that should be submited to the
     * jaferClientBean when the thread is executed
     */
    private Object query;

    /**
     * Stores a reference to logger instance
     */
    private static Logger logger = Logger.getLogger("org.jafer.databeans");

    /**
     * Stores a reference to exception that occured in the last search or null
     * if no errors occured
     */
    private JaferException searchException = null;

    /**
     * Sets the offsets for this ActiveBean result set in respect to the super
     * result set of all the ActiveBeans
     *
     * @param start The starting offset index
     * @param end The ending offset index
     */
    public void setOffsets(int start, int end)
    {
        this.startOffset = start;
        this.endOffset = end;
    }

    /**
     * Returns a boolean to indicate if the record index supplied is contained
     * with in the result set of this ActiveBean. IE that the record index is
     * between the offsets.
     *
     * @param recordIndex The index to search for
     * @return true if the record is contained in this ActiveBean
     */
    public boolean containsRecord(int recordIndex)
    {
        return (recordIndex >= startOffset && recordIndex <= endOffset);
    }

    /**
     * Gets a reference to the JaferClientBean for this ActiveBean
     *
     * @return The instance of the DataBean
     */
    public Databean getDatabean()
    {
        return databean;
    }

    /**
     * sets a reference to the JaferClientBean for this ActiveBean
     *
     * @param bean The JaferClientBean to store in this ActiveBean
     */
    public void setDatabean(Databean bean)
    {
        this.databean = bean;
    }

    /**
     * This method returns the JaferException from the last search.
     *
     * @return JaferException instance or null if no errors were found
     */
    public JaferException getSearchException()
    {
        return this.searchException;
    }

    /**
     * This method sets the last exception that occurred during a search
     *
     * @param exc The exception that occurred
     */
    protected void setSearchException(JaferException exc)
    {
        this.searchException = exc;
    }

    /**
     * Set the query that will be executed when this ActiveBeans thread is run
     *
     * @param query The query to execute
     * @param schema The schema used to auto populate cache
     */
    public void submitQuery(Object query, String schema)
    {
        // if the query is of type Node we need to import it into a new document
        if (query instanceof Node)
        {
            this.query = DOMFactory.newDocument().importNode((Node) query, true);
        }
        // if the query is of type JaferQuery we need to import it into a new
        // document
        else if (query instanceof JaferQuery)
        {
            // if jafer then import the node
            this.query = DOMFactory.newDocument().importNode(((JaferQuery) query).getQuery(), true);
        }
        else
        {
            this.query = query;
        }
        // set the schema to use when prepopulating the cache
        setPrepoulateCacheRecordSchema(schema);

        // set flag to indicate we have started a search. Need to do this here
        // to avoid this call returning and processing results before the thread
        // itself has set this flag
        stillSearching(true);
        // start the thread running
        start();

    }

    /**
     * get the query that will be executed when this ActiveBeans thread is run
     *
     * @return The query to be executed
     */
    public Object getQuery()
    {
        return query;
    }

    /**
     * Set the record schema to use when prepoulating cache
     *
     * @param recordSchemamThe schema to prepopulate the cache with
     */
    protected void setPrepoulateCacheRecordSchema(String recordSchema)
    {
        this.cacheRecordSchema = recordSchema;
    }

    /**
     * Get the record schema to use when prepoulating cache
     *
     * @return The schema for prepoulating the cache
     */
    protected String getPrepoulateCacheRecordSchema()
    {
        return cacheRecordSchema;
    }

    /**
     * Get the number of results that were found the last time the ActiveBeans
     * thread was executed
     *
     * @return The number of results found
     */
    public int getNumberOfResults()
    {
        // make sure the bean is configured else retun no results
        if (this.databean != null)
        {
            return ((Search) this.databean).getNumberOfResults();
        }
        return 0;
    }

    /**
     * Retrieve the record at the specified recordIndex
     *
     * @param recordIndex The recordIndex to retrieve
     * @param schema The schema to apply
     * @return The retrieved record
     * @throws JaferException
     */
    public Field getRecord(int recordIndex, String schema) throws JaferException
    {
        // make sure a schema is entered
        if (schema == null || schema.length() == 0)
        {
            throw new JaferException("Record Schema must be set to retrieve a record");
        }
        // get the record applying the offsets
        return getRecord(recordIndex, schema, true);
    }

    /**
     * Retrieve the record at the specified recordIndex
     *
     * @param recordIndex The recordIndex to retrieve
     * @param schema The schema to apply
     * @param applyOffsets Should the offsets be applied to the record index,
     *        This is normally true apart from when the autopopulation of cache
     *        needs to refer to local indexs
     * @return The retrieved record
     * @throws JaferException
     */
    protected synchronized Field getRecord(int recordIndex, String schema, boolean applyOffsets) throws JaferException
    {
        // make sure the bean is configured
        if (this.databean != null)
        {
            // make sure this ActiveBean contains the record when we are
            // applying offsets
            if (applyOffsets && containsRecord(recordIndex) == false)
            {
                throw new RecordException("The record is not contained by this ActiveBean");
            }

            // set the record schema and cursor position for retreival
            // applying the offsets to obtain the position in just this
            // activeBeans result set
            ((Present) this.databean).setRecordSchema(schema);

            // set the record cursor applying off sets if required
            if (applyOffsets)
            {
                // apply offsets
                ((Present) this.databean).setRecordCursor(recordIndex - this.startOffset + 1);
            }
            else
            {
                // use straight record index
                ((Present) this.databean).setRecordCursor(recordIndex);
            }

            // return the current record
            return ((Present) this.databean).getCurrentRecord();

        }
        throw new RecordException("The databean for this ActiveBean is not configured");
    }

    /**
     * This method checks if the search is still executing
     *
     * @return Returns the false if the search has completed.
     */
    public boolean stillSearching()
    {
        return stillSearching;
    }

    /**
     * This method sets the flag to indicate if the search is executing or not
     *
     * @param searchStatus The search status - true if executing search
     */
    protected void stillSearching(boolean searchStatus)
    {
        stillSearching = searchStatus;
    }

    /**
     * Returns whether this active bean should prepopulate cache after search
     *
     * @return Returns true is auto population of cache should take place
     */
    public boolean autoPopulateCache()
    {
        return autoPopulateCache;
    }

    /**
     * Sets whether this active bean should prepopulate cache after search
     *
     * @param autoPopulate true if the cache should be auto populated
     */
    public void setAutoPopulateCache(boolean autoPopulate)
    {
        this.autoPopulateCache = autoPopulate;
    }

    /**
     * This method allows the caller to set the stop active bean search flag
     */
    public void stopActiveBeanSearch(boolean stopStatus)
    {
        this.stopActiveBeanSearch = stopStatus;
    }

    /**
     * Checks to see if the search should be stopped premeturely
     *
     * @return true if search process should terminate early
     */
    protected boolean stopActiveBeanSearch()
    {
        return this.stopActiveBeanSearch;
    }

    /**
     * Executes the thread to perform the search
     */
    public void run()
    {
        try
        {
            // stores the number of results found
            int results = 0;
            logger.fine("Starting search on thread - " + getName());
            // reset the stop flag
            this.stopActiveBeanSearch = false;
            // set flag to indicate we have started a search
            stillSearching(true);
            // ensure last search exception is nulled out
            setSearchException(null);
            // set the offsets back to 0
            setOffsets(0, 0);
            // make sure the bean is configured to execute search
            if (this.databean != null)
            {
                // perform the search
                results = ((Search) this.databean).submitQuery(this.query);

                logger.fine("Search on " + this.getName() + " found " + Integer.toString(results)
                        + " results, bean also reports " + ((Search) this.databean).getNumberOfResults());
            }
            // set flag to indicate we have completed search part of thread
            stillSearching(false);
            logger.fine("search completed on thread - " + getName());
            // if prefilling of the cache is enabled start this process
            if (autoPopulateCache())
            {
                // make sure we have a schema set on the active bean
                if (getPrepoulateCacheRecordSchema() == null || getPrepoulateCacheRecordSchema().length() == 0)
                {
                    throw new JaferException("Record Schema must be set to search when prepopulating of the cache is enabled");
                }

                logger.fine("Cache free slots: " + ((Cache) databean).getAvailableSlots() + " on thread - " + getName());

                Cache cacheBean = (Cache) databean;
                // fill the cache with records until:
                // * all the result records have been processed,
                // * the user prematurely stops the process,
                // * the cache runs out of available slots and is therefore full
                // * either the available slots are less than the fetch size
                // (as performing another retrieve would wipe out the first x
                // records) or there are less records than the fetch size to be
                // added and they are greater than the available slotsrecords.
                // 
The index is moved on by the fetch size as retreiving one // record will auto retrieve the next X records for (int index = 1; index <= results && stopActiveBeanSearch == false && cacheBean.getAvailableSlots() > 0 && (cacheBean.getAvailableSlots() >= cacheBean.getFetchSize() || cacheBean.getAvailableSlots() >= results + 1 - index); index += cacheBean.getFetchSize()) { logger.fine("Caching Record " + index + " on thread - " + getName()); // get the record which will automatically add it into the // cache if it does not already exist, set apply offsets to // false as this is already a local index getRecord(index, getPrepoulateCacheRecordSchema(), false); } } } catch (JaferException exc) { // something went wrong searching this bean so output problem as a // warning as it may just be that the client is not on-line at // present String message = "Jafer Exception in databeanManager ActiveBean( " + this.getName() + ") performing search: " + exc.toString(); // set the exception so it can be retrieved later setSearchException(exc); logger.warning(message); exc.printStackTrace(); } catch (Exception exc) { // something went wrong searching this bean so output problem as a // warning as it may just be that the client is not on-line at // present String message = "Unexpected Exception in databeanManager ActiveBean( " + this.getName() + ") performing search: " + exc.toString(); // set the exception so it can be retrieved later setSearchException(new JaferException(message, exc)); logger.warning(message); exc.printStackTrace(); } finally { logger.fine("stopping search on thread - " + getName()); // set flag to indicate we have completed search part of thread stillSearching(false); } } } /** * This class manages a collection of databases */ public class DatabeanManager extends Databean implements Present, Search { /** * Stores a reference to factories that can create databeans for specified * databases. A map entry consists of key = database name and value = * factory that creates a databean supporting Search and Present for the * specified database */ private Hashtable databeanFactories; /** * Stores a reference to cache factory that provides the cache for the * ActiveBeans data bean to use. If this is set to null then the cache will * not be set on the databean and the databeans internal one will be used */ private CacheFactory cacheFactory = null; /** * Stores a reference to whether pre filling of the caching is enabled or * not. Enabled (true) as default. */ private boolean autoPopulateCache = true; /** * Stores a reference to an array of active beans forthe current set of * databases */ private ActiveBean[] activeBeans = new ActiveBean[0]; /** * Stores a reference to current record cursor position */ private int recordCursor; /** * Stores a reference to record schema that should be applied when * retrieving records */ private String recordSchema; /** * Stores a reference to search mode.
*
*
    *
  • serial - The first active bean to return a result set will be used, * ignoring all other activebean results
  • *
  • parallel - All ActiveBeans results will be combined to provide a * super result set (DEFAULT)
  • *
*/ private String mode; /** * Stores a reference to the total number of records retrieved */ private int totalRecords = 0; /** * Stores a reference to the name of this databeanmanager */ private String name; /** * Stores a reference to this databeanmanagers complete set of configured * databases */ private String[] allDatabases; /** * Set the databean factories that this databeanmanager supports * * @param databeanFactories A map where key = database name and value = * factory that creates a databean supporting Search and Present for * the specified database */ public void setDatabeanFactories(Hashtable databeanFactories) { // avoid case sensitive database names by converting keys to lowercase this.databeanFactories = new Hashtable(); // loop round all the keys Enumeration en = databeanFactories.keys(); while (en.hasMoreElements()) { // get the key and value for the databean factory String database = ((String) en.nextElement()); Object value = databeanFactories.get(database); // add to internal databean factories map turning database name to // lower case this.databeanFactories.put(database.toLowerCase(), value); } } /** * Returns a map of the supported databean factories * * @return the supported databean factories map */ public Map getDatabeanFactories() { return databeanFactories; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#setRecordCursor(int) */ public void setRecordCursor(int recordCursor) throws JaferException { this.recordCursor = recordCursor; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#getRecordCursor() */ public int getRecordCursor() { return recordCursor; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#setRecordSchema(java.lang.String) */ public void setRecordSchema(String recordSchema) { this.recordSchema = recordSchema; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#getRecordSchema() */ public String getRecordSchema() { return recordSchema; } /** * Returns whether the active beans should prepopulate cache after search * * @return Returns true is auto population of cache should take place */ public boolean autoPopulateCache() { return autoPopulateCache; } /** * Sets whether the active beans should prepopulate cache after search * * @param autoPopulate true if the cache should be auto populated */ public void setAutoPopulateCache(boolean autoPopulate) { this.autoPopulateCache = autoPopulate; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#setDatabases(java.lang.String) */ public void setDatabases(String database) { // make sure a database is specified. If the DatabeanManagerFactory is // not set up correctly that could mean null being passed here if (database != null) { this.setDatabases(new String[] { database }); } else { // reset active beans back to an empty array so search will return // nothing if it is executed rather than the last set of databases // results activeBeans = new ActiveBean[0]; } } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#setDatabases(java.lang.String[]) */ public void setDatabases(String[] databases) { // reset active beans back to an empty array so search will return // nothing if it is executed rather than the last set of databases // results activeBeans = new ActiveBean[0]; // Make sure we have databases to set if (databases == null || databases.length == 0) { return; } // if the first database name equals the name of this database then use // it's configured set of databases if they are set and not null if (databases[0].equalsIgnoreCase(this.getName()) && this.allDatabases != null) { databases = this.allDatabases; } // create a new array of active beans for the new set of databases to // search now we know we definitly have some to set activeBeans = new ActiveBean[databases.length]; // for each database create the active bean into the array for (int index = 0; index < databases.length; index++) { // convert the database name supplied to lower case for searching // databeanfactories String database = databases[index].toLowerCase(); if (databeanFactories.containsKey(database)) { // get the datbean factory for the database and create a new // databean DatabeanFactory factory = (DatabeanFactory) databeanFactories.get(database); Databean databean = factory.getDatabean(); // set the cache on the databean if we have a cache factory // defined inside this databeanmanager if (getCacheFactory() != null) { // convert the databean to a cache interface to set the // cache from the factory ((Cache) databean).setCache(getCacheFactory().getCache()); } // create an active bean and set its databean with the one // obtained from the factory activeBeans[index] = new ActiveBean(); activeBeans[index].setDatabean(databean); // name the activebean thread after the database it searches activeBeans[index].setName(database); } } } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#getDatabases() */ public String[] getDatabases() { // create a string array to return all the names of the databases // currently active String[] databases = new String[activeBeans.length]; for (int index = 0; index < activeBeans.length; index++) { // make sure the activebean was configured correctly if (activeBeans[index] != null) { // store the name of the active bean into databases return // result. databases[index] = activeBeans[index].getName(); } else { // active bean was configured incorrectly so set database name // to error databases[index] = "ERROR - NOT FOUND"; } } return databases; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#submitQuery(java.lang.Object) */ public int submitQuery(Object query) throws JaferException { // if the active beans are currently caching stop them now as we are // preforming a new search stopAutoPopulateCache(); // make sure we have active beans to search if (activeBeans.length == 0) { // throw error as trying to search no databases throw new JaferException("Unable to search - No databases were found", 235, ""); } // make sure record schema not null to search with auto populate caching // on if (getRecordSchema() == null && autoPopulateCache()) { throw new JaferException("Record Schema must be set to search when prepopulating of the cache is enabled"); } // set the total records found back to 0 totalRecords = 0; // loop round each activebean for (int index = 0; index < activeBeans.length; index++) { // make sure the active bean is valid and has its data bean set if (activeBeans[index] == null || activeBeans[index].getDatabean() == null) { throw new JaferException("Unable to search - Specified database was not found", 235, ""); } // tell the bean if it should auto populate activeBeans[index].setAutoPopulateCache(autoPopulateCache()); // set the query on the active bean and start the search thread activeBeans[index].submitQuery(query, getRecordSchema()); } // set current record to find to 1; int currentRecord = 1; // loop round each active bean for (int index = 0; index < activeBeans.length; index++) { // wait until the active bean has completed it's search by checking // if it is still searching. Can not check thread alive status as // ActiveBean may have started to cache data while (activeBeans[index].stillSearching()) { // yield this thread to give active bean chance to execute Thread.yield(); } // bean has now completed search so see how many records were found int recordsFound = activeBeans[index].getNumberOfResults(); // did we find any records? if (recordsFound > 0) { // yes records were found so we need to set the offsets for the // active bean // Hence it should start at the current record and end at the // current record + the records found -1 activeBeans[index].setOffsets(currentRecord, currentRecord + recordsFound - 1); // update the current record to add on the number of records // found so the offset is increase for the next active bean // processed currentRecord += recordsFound; totalRecords += recordsFound; // check if we are running mode serial if (mode.equalsIgnoreCase(DatabeanManagerFactory.MODE_SERIAL)) { // yes so break the entire loop as we no longer need to // process any more active beans as we are only going to // return the result set from this active bean break; } } } // return the toal number of records found return totalRecords; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#getNumberOfResults() */ public int getNumberOfResults() { return totalRecords; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#getNumberOfResults(java.lang.String) */ public int getNumberOfResults(String databaseName) { // loop round active beans for (int index = 0; index < activeBeans.length; index++) { // make sure active bean is configured if (activeBeans[index] != null) { // does the name of the database match the name of the active // bean if (activeBeans[index].getName().equalsIgnoreCase(databaseName)) { return activeBeans[index].getNumberOfResults(); } } } return -1; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#getCurrentRecord() */ public Field getCurrentRecord() throws org.jafer.exception.JaferException { // loop round active beans for (int index = 0; index < activeBeans.length; index++) { // make sure active bean is configured if (activeBeans[index] != null) { // check to see if this active bean contains the record if (activeBeans[index].containsRecord(this.recordCursor)) { // return the record return activeBeans[index].getRecord(this.recordCursor, this.recordSchema); } } } throw new JaferException("Record Cursor Out of Range"); } /* * (non-Javadoc) * * @see org.jafer.interfaces.Present#getCurrentDatabase() */ public String getCurrentDatabase() throws JaferException { // loop round active beans for (int index = 0; index < activeBeans.length; index++) { // make sure active bean is configured if (activeBeans[index] != null) { // does this active bean contain the record if (activeBeans[index].containsRecord(this.recordCursor)) { // return the beans database name return activeBeans[index].getName(); } } } throw new JaferException("Record Cursor Out of Range"); } /** * Currently Not Supported * * @see org.jafer.interfaces.Present#setCheckRecordFormat(boolean) */ public void setCheckRecordFormat(boolean checkRecordFormat) { /** @todo Implement this org.jafer.interfaces.Present method */ throw new java.lang.UnsupportedOperationException("Method setCheckRecordFormat() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Present#isCheckRecordFormat() */ public boolean isCheckRecordFormat() { /** @todo Implement this org.jafer.interfaces.Present method */ throw new java.lang.UnsupportedOperationException("Method isCheckRecordFormat() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Present#setElementSpec(java.lang.String) */ public void setElementSpec(String elementSpec) { /** @todo Implement this org.jafer.interfaces.Present method */ throw new java.lang.UnsupportedOperationException("Method setElementSpec() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Present#getElementSpec() */ public String getElementSpec() { /** @todo Implement this org.jafer.interfaces.Present method */ throw new java.lang.UnsupportedOperationException("Method getElementSpec() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#setResultSetName(java.lang.String) */ public void setResultSetName(String resultSetName) { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method setResultSetName() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#getResultSetName() */ public String getResultSetName() { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method getResultSetName() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#setParseQuery(boolean) */ public void setParseQuery(boolean parseQuery) { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method setParseQuery() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#isParseQuery() */ public boolean isParseQuery() { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method isParseQuery() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#saveQuery(java.lang.String) */ public void saveQuery(String file) throws JaferException { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method saveQuery() not yet implemented."); } /** * Currently Not Supported * * @see org.jafer.interfaces.Search#getQuery() */ public Object getQuery() { /** @todo Implement this org.jafer.interfaces.Search method */ throw new java.lang.UnsupportedOperationException("Method getQuery() not yet implemented."); } /** * Set the mode that this databeanManager runs in * * @param mode The mode to set use statics in DatabeanManagerFactory */ public void setMode(String mode) { this.mode = mode; } /** * get the mode that the DatabeanManager is running in * * @return The current mode Serial or Parallel */ public String getMode() { return mode; } /** * Set the name of this DataBeanManager * * @param name The name of the databean manager */ public void setName(String name) { this.name = name; } /** * get the name of the DataBeanManager * * @return the name of the databean manager */ public String getName() { return name; } /** * Set the databeanManagers set of all databases it processes. All the * databases must be configured in the databeanfactories for the * databeanManager * * @param allDatabases the array of database names */ public void setAllDatabases(String[] allDatabases) { this.allDatabases = allDatabases; } /** * Get the databeanManagers set of all databases it processes * * @return An array of all the database names */ public String[] getAllDatabases() { return allDatabases; } /** * Sets the cache factory to be used by the DatabeanManager * * @param cacheFactory the cache factory to use */ public void setCacheFactory(CacheFactory cacheFactory) { this.cacheFactory = cacheFactory; } /** * Returns the cache factory used by this databeanManager * * @return The cache factory used */ public CacheFactory getCacheFactory() { return cacheFactory; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#getSearchDiagnostic(java.lang.String) */ public JaferException getSearchException(String database) { // make sure database name specified if (database != null) { // get the JaferException for the database, empty arry if no errors // found JaferException[] errors = getSearchException(new String[] { database }); if (errors.length != 0) { // return the first JaferException return errors[0]; } } return null; } /* * (non-Javadoc) * * @see org.jafer.interfaces.Search#getSearchDiagnostics(java.lang.String[]) */ public JaferException[] getSearchException(String[] databases) { // create empty array for success condition ArrayList errors = new ArrayList(); // Make sure we have databases to set if (databases == null || databases.length == 0) { // return an empty array return new JaferException[0]; } // if the first database name equals the name of this database then use // it's configured set of databases if they are set and not null if (databases[0].equalsIgnoreCase(this.getName()) && this.allDatabases != null) { databases = this.allDatabases; } // loop round active beans for (int index = 0; index < databases.length; index++) { // loop round active beans for (int activeBeanIndex = 0; activeBeanIndex < activeBeans.length; activeBeanIndex++) { // make sure active bean is configured if (activeBeans[activeBeanIndex] != null) { // does this active bean match the database name if (databases[index] != null && activeBeans[activeBeanIndex].getName().equalsIgnoreCase(databases[index])) { errors.add(activeBeans[activeBeanIndex].getSearchException()); } } } } // convert the array list back to an Array return (JaferException[]) errors.toArray(new JaferException[databases.length]); } /* * (non-Javadoc) * * @see java.lang.Object#finalize() */ protected void finalize() throws Throwable { stopAutoPopulateCache(); super.finalize(); } /** * This method stops any auto caching that may being performed by the * databean manager in seperate threads to prempt and speed up retrieval. *
*
* This is important as the databean manager will continue to cache * records if the setting is enabled until this method is called, a new * query is submitted or the databean manager is garbage collected */ public void stopAutoPopulateCache() { // before the DatabeanManager can be cleaned up it needs to stop any // active bean threads that may still be running for (int activeBeanIndex = 0; activeBeanIndex < activeBeans.length; activeBeanIndex++) { // make sure active bean is configured if (activeBeans[activeBeanIndex] != null) { // tell the bean to stop hence cleaning up correctly activeBeans[activeBeanIndex].stopActiveBeanSearch(true); // loop while the active bean still alive while (activeBeans[activeBeanIndex].isAlive()) { // yield this thread to give active bean chance to execute Thread.yield(); } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy