view gnv-artifacts/src/main/java/de/intevation/gnv/state/cache/ThematicDataCacheCleaner.java @ 1109:2b4d197a538c

Fixed the time range validation - introduced an epsilon of one second for valid time ranges (issue286). gnv-artifacts/trunk@1240 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 29 Jun 2010 09:07:26 +0000
parents dfd02f8d3602
children f953c9a559d8
line wrap: on
line source
/**
 *
 */
package de.intevation.gnv.state.cache;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import net.sf.ehcache.Cache;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import de.intevation.artifactdatabase.Config;
import de.intevation.gnv.artifacts.cache.CacheFactory;
import de.intevation.gnv.geobackend.base.query.cache.CacheCleaner;
import de.intevation.gnv.geobackend.base.query.container.QueryContainerFactory;
import de.intevation.gnv.geobackend.base.query.container.exception.QueryContainerException;
import de.intevation.gnv.geobackend.base.query.exception.QueryException;
import de.intevation.gnv.state.StateBase;
import de.intevation.gnv.utils.ArtifactXMLUtilities;


/**
 * Extended Class of the CacheCleaner.
 * This Cleaner has the job to cleanup the ThematicData-Cache if it
 * is necessary.
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 *
 */
public class ThematicDataCacheCleaner extends CacheCleaner {

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

    private final static String XPATH_ARTIFACTS =
                                    "/artifact-database/artifacts/artifact";
    private final static String XPATH_STATES = "states/state";
    private final static String XPATH_STATEID = "id";
    private final static String XPATH_QUERYID = "queryID";

    /**
     * The Queries that should be Cleaned with its links to the
     * StateIds.
     */
    private Collection<QueryObject> queryObjects = null;

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

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

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

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

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

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

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

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

    /**
     * Initializes the QueryObjects.
     * The Queryobjects will be read from the Configuration.
     * Only Queries which are defined in <code>queryID</code>-Elements
     * are used.
     * The other Queries are currently not put into the Cache.
     */
    @Override
    protected void setUp(){
        super.setUp();
        this.queryObjects = new ArrayList<QueryObject>();
        Document configuration = Config.getConfig();
        NodeList artifactList = Config.getNodeSetXPath(configuration,
                                                       XPATH_ARTIFACTS);
        log.debug("ThematicDataCacheCleaner.setUp()");
        if (artifactList != null && artifactList.getLength() > 0){
            for (int i = 0; i < artifactList.getLength(); i++){
                Element currentArtifactNode = (Element)artifactList.item(i);

                String link = currentArtifactNode.getAttribute("xlink:href");
                if (link != null && link.length() > 0){
                    String absolutFileName = Config.replaceConfigDir(link);
                    currentArtifactNode = (Element)new ArtifactXMLUtilities()
                                           .readConfiguration(absolutFileName);
                }
                NodeList stateList = Config.getNodeSetXPath(currentArtifactNode,
                                                            XPATH_STATES);
                if (stateList != null && stateList.getLength() > 0){
                    for (int j = 0; j < stateList.getLength() ; j++){
                        Element currentStateNode = (Element)stateList.item(j);
                        String stateId = currentStateNode
                                          .getAttribute(XPATH_STATEID);
                        String queryID = Config.getStringXPath(currentStateNode,
                                                                XPATH_QUERYID);
                        try {
                            if (queryID != null){
                                String query = QueryContainerFactory
                                                    .getInstance()
                                                    .getQueryContainer()
                                                    .getQuery(queryID);
                                QueryObject qo = new QueryObject(stateId, query);
                                queryObjects.add(qo);
                            }
                        } catch (QueryContainerException e) {
                            log.error(e,e);
                        }
                    }
                }
            }
        }
    }

    @Override
    protected void cleanup() {
        log.debug("ThematicDataCacheCleaner.cleanup");
        try {
            if (queryObjects != null && queryObjects.size() > 0){
                String[] tableNames = this.getUpdatedTableNames();
                if (tableNames != null && tableNames.length > 0){
                    Iterator<QueryObject> it = queryObjects.iterator();
                    while (it.hasNext()){
                        QueryObject qo = it.next();
                        for (int i = 0; i < tableNames.length; i++){
                            if (qo.queryContainsTableName(tableNames[i])){
                                String stateId = qo.getStateId();
                                this.cleanUpCache(stateId);
                                break;
                            }
                        }
                    }
                }else{
                    log.debug("No Tables found to cleanup.");
                }
            }else{
                log.warn("No Queries to clean");
            }
        } catch (QueryException e) {
            log.error(e,e);
        }
    }

    /**
     * Removes the Entries which Keys matches to the <code>stateId</code>
     * from the Cache.
     * @param stateId The Id of the State which Entries has to be removed.
     */
    private void cleanUpCache(String stateId){
        log.debug("ThematicDataCacheCleaner.cleanUpCache "+stateId);
        CacheFactory factory = CacheFactory.getInstance();
        Cache cache = factory.getCache();
        List<String> keys = cache.getKeys();
        String keySample = StateBase.HASH_ID_SEPARATOR +
                     stateId +
                     StateBase.HASH_ID_SEPARATOR;
        if (keys != null && keys.size() > 0){
            Iterator<String> it = keys.iterator();
            while (it.hasNext()){
                String key = it.next();
                if (key != null && key.contains(keySample)){
                    boolean removed = cache.remove(key);
                    if (!removed){
                        log.warn("Object with Key " +
                                 key + "could not be removed from Cache");
                    }else{
                        log.debug("Object with Key " +
                                 key + "has been removed from Cache");
                    }
                }
            }
        }
    }
}

http://dive4elements.wald.intevation.org