view geo-backend/src/main/java/de/intevation/gnv/geobackend/base/query/cache/CacheCleaner.java @ 897:02cd2935b5fa

Removed trailing whitespace. geo-backend/trunk@1013 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 28 Apr 2010 07:04:19 +0000
parents eb777022b628
children ebeb56428409
line wrap: on
line source
/**
 *
 */
package de.intevation.gnv.geobackend.base.query.cache;

import java.sql.Date;
import java.util.Collection;
import java.util.Iterator;

import org.apache.log4j.Logger;

import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.geobackend.base.query.DefaultQueryExceutor;
import de.intevation.gnv.geobackend.base.query.QueryExecutor;
import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
import de.intevation.gnv.geobackend.base.query.exception.QueryException;
import de.intevation.gnv.geobackend.util.DateUtils;

/**
 * Thread that looks every n - Minutes if an Cache has to be cleanedup.
 * You can configure the Timeout in Seconds using the Systemproperty
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 *
 */
public class CacheCleaner extends Thread {

    /**
     * the logger, used to log exceptions and additonaly information
     */
    private static Logger log = Logger.getLogger(CacheCleaner.class);

    /**
     * The Systemproperty-identifier for the Configuration of the TimeInterval
     */
    public static final String CACHE_CLEANER_INTERVAL = "caching.cleaner.interval";

    /**
     * The Time To wait between two Cleanups.
     */
    private long timeout = 1000 * 60; // 1 Minute

    /**
     * The Border which has to be used to Query the updated Tables.
     */
    private long lowerBorderTime = 0;

    /**
     * The Id to Lookup the SQL-Statement for fetchung the Names of the
     * updated Tables.
     */
    private String queryID = "updated_tables";

    /**
     * Constructor
     */
    public CacheCleaner() {
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     */
    public CacheCleaner(Runnable arg0) {
        super(arg0);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     */
    public CacheCleaner(String arg0) {
        super(arg0);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     * @param arg1
     */
    public CacheCleaner(ThreadGroup arg0, Runnable arg1) {
        super(arg0, arg1);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     * @param arg1
     */
    public CacheCleaner(ThreadGroup arg0, String arg1) {
        super(arg0, arg1);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     * @param arg1
     */
    public CacheCleaner(Runnable arg0, String arg1) {
        super(arg0, arg1);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     * @param arg1
     * @param arg2
     */
    public CacheCleaner(ThreadGroup arg0, Runnable arg1, String arg2) {
        super(arg0, arg1, arg2);
        this.setUp();
    }

    /**
     * Constructor
     * @param arg0
     * @param arg1
     * @param arg2
     * @param arg3
     */
    public CacheCleaner(ThreadGroup arg0, Runnable arg1, String arg2, long arg3) {
        super(arg0, arg1, arg2, arg3);
        this.setUp();
    }

    /**
     * Sets up the members of the CacheCleaner.
     */
    protected void setUp(){
        String intervalValue = System.getProperty(CACHE_CLEANER_INTERVAL);
        if (intervalValue != null){
            log.info("Set Interval to "+intervalValue+" Seconds");
            try {
                this.timeout = Long.parseLong(intervalValue) * 1000;
            } catch (NumberFormatException e) {
                log.error(e,e);
            }
        }
    }

    /**
     * This Method can be used do run the Main-Mechanism of the Thread e.g
     * from a Unittest.
     * @return
     */
    public boolean test(){
        log.debug("CacheCleaner.test");
        this.cleanup();
        return true;
    }

    @Override
    public void run() {
        log.debug("CacheCleaner.run");
        long requiredTime = 0;
        this.lowerBorderTime = System.currentTimeMillis();
        while (true){
            long startTime = 0;
            try {
                long nextTimeout = timeout-requiredTime;
                if (nextTimeout > 0){
                    Thread.sleep(nextTimeout);
                }
                startTime = System.currentTimeMillis();
                log.debug("Sleep "+nextTimeout+"ms cleanup Cache now");
                this.cleanup();
            } catch (InterruptedException e) {
                log.error(e,e);
            } catch (Exception e){
                log.error(e,e);
            }  catch (Throwable t){
                log.error(t,t);
            }finally{
                requiredTime = System.currentTimeMillis() - startTime;
                log.debug("CleanUp required "+requiredTime);
            }
        }
    }

    /**
     * Method that do the Cleanup-Work
     */
    protected void cleanup(){
        log.debug("CacheCleaner.cleanup");
        try {
            // We have to go this Way to avoid using the Cache for this Query.
            String[] tableNames = this.getUpdatedTableNames();
            if (tableNames != null){
                QueryExecutorFactory.getInstance()
                                    .getQueryExecutor().clearCache(tableNames);
            }
        } catch (QueryException e) {
            log.error(e,e);
        }

    }

    /**
     * Returns the Names of the Tables which have been updated.
     * @return the Names of the Tables which have been updated.
     * @throws QueryException
     */
    protected String[] getUpdatedTableNames()throws QueryException {
        String[] tableNames = null;
        QueryExecutor queryExecutor = new DefaultQueryExceutor();
        Date date = new Date(this.lowerBorderTime);
        this.lowerBorderTime = System.currentTimeMillis();
        log.debug("New Lookup at "+DateUtils.getPatternedDateAmer(new Date(lowerBorderTime)));
        String queryDate = DateUtils.getPatternedDateAmer(date);
        Collection<Result> result = queryExecutor.
                                      executeQuery(queryID,
                                                   new String[]{queryDate});
        if (result != null && !result.isEmpty()){
            tableNames = new String[result.size()];
            Iterator<Result> it = result.iterator();
            int i = 0;
            while (it.hasNext()){
                tableNames[i++] = it.next().getString(0).toUpperCase();
                log.debug("Table that was updated: "+tableNames[i-1]);
            }
        }
        return tableNames;
    }
}

http://dive4elements.wald.intevation.org