Package org.enhydra.jdbc.util

Source Code of org.enhydra.jdbc.util.RequestCache

package org.enhydra.jdbc.util;

import java.util.Hashtable;
import java.util.Enumeration;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.util.regex.Pattern;
import java.util.StringTokenizer;

import org.enhydra.jdbc.util.Logger;

import org.apache.commons.logging.LogFactory;


public class RequestCache {
  // the cache objects
  // there are only the requests found in the configuration file
  private static Hashtable cache_ = null;

  private static Hashtable dsCache_ = null;

  // all requests , given by the application
  // be careful, this object may be large, but with a minimum of
  // object size (only String objects stored in the value part)
  private static Hashtable requests_ = null;

  // the current singleton object
  private static RequestCache theCache_ = null;

  private long timeToLive_ = 86400000; // 1 day

  private String path = null;

  private static Logger logger;

  /**
   * This method is used to obtain the cache, if it does not exist, it creates
   * it
   */
  public static synchronized RequestCache getInstance() {
    if (theCache_ == null) {
      theCache_ = new RequestCache();
    }
    return theCache_;
  }

  public static synchronized RequestCache getInstance(String path) {
    if (theCache_ == null) {
      theCache_ = new RequestCache(path);
    }
    return theCache_;
  }

  public RequestCache() {
    if (logger == null)
      logger = new Logger(LogFactory.getLog("org.enhydra.jdbc.util"));

    if (cache_ == null)
      cache_ = new Hashtable();

    if (requests_ == null)
      requests_ = new Hashtable();

    if (dsCache_ == null)
      dsCache_ = new Hashtable();

    readConfigurationFile();
  }

  public RequestCache(String path) {
    if (cache_ == null)
      cache_ = new Hashtable();

    if (requests_ == null)
      requests_ = new Hashtable();

    this.path = path;

    readConfigurationFile();
  }

  public void readConfigurationFile() {
    if (path != null) {
      try {
        logger
            .debug("RequestCache: readConfigurationFile try to open file="
                + path);
        FileInputStream fstream = new FileInputStream(path);
        DataInputStream in = new DataInputStream(fstream);
        logger
            .debug("RequestCache: readConfigurationFile open done file="
                + path);

        while (in.available() != 0) {
          String req = ((String) in.readLine()).trim();
          logger.debug("RequestCache:readConfigurationFile line:"
              + req);
          if (!req.startsWith("#")) {
            long ttl = timeToLive_;
            String newreq = null;
            if (req.startsWith("ttl")) {
              StringTokenizer st = new StringTokenizer(req);
              String ttls = st.nextToken();
              logger
                  .debug("RequestCache:readConfigurationFile ttls:<"
                      + ttls + ">");
              ttl = Integer.parseInt(ttls.substring(4));
              newreq = req.substring(ttls.length()).trim();
            } else
              newreq = req;

            Pattern p = Pattern.compile(newreq);
            logger
                .debug("RequestCache:readConfigurationFile newreq:<"
                    + newreq + ">");
            logger.debug("RequestCache:readConfigurationFile ttl:<"
                + ttl + ">");
            RequestCacheObject uco = new RequestCacheObject(newreq,
                p, ttl);
            cache_.put(newreq, uco);
          }
        }

        in.close();
      } catch (Exception e) {
        System.err.println("File input error");
        e.printStackTrace();
      }
    }
  }

  public boolean isInCache(String req) {
    if (cache_ != null)
      if (cache_.size() == 0)
        return false;

    if ((cache_ == null) || (requests_ == null) || (req == null)
        || (req.compareTo("") == 0)) {
      return false;
    }

    // optimization for the real life, all application requests
    // may be found in the requests object, and we need to save time
    String redir = (String) requests_.get(req);
    if (redir != null) {
      if (redir.compareTo("null") != 0) {
        // logger.debug("RequestCache:isInCache requests_
        // contains(req)");
        return ((RequestCacheObject) (cache_.get(redir))).isAlive();
      } else
        // this is a non-cacheable request
        return false;

    } else {

      // if the cache contains the sql request
      if (cache_.containsKey(req)) {
        // logger.debug("RequestCache:isInCache contains(req)");
        return ((RequestCacheObject) (cache_.get(req))).isAlive();
      } else {
        // if the cache does not contain the sql request
        // we are going to test all items in cache to test the pattern
        for (Enumeration e = cache_.keys(); e.hasMoreElements();) {
          RequestCacheObject uco = (RequestCacheObject) (cache_.get(e
              .nextElement()));
          if (uco.getPattern().matcher(req).matches()) {
            // if it matches, return if the RequestCacheObject is
            // alive
            // logger.debug("RequestCache:isInCache
            // contains(pattern)");
            return uco.isAlive();
          }
        }
      }
    }

    return false;
  }

  public synchronized void setResult(String req, Object rset) {

    // if the cache exists and the sql request (or pattern) is not null
    if ((cache_ != null) && (req != null)) {
      // first remove the RequestCacheObject to the cache
      RequestCacheObject uco = (RequestCacheObject) (cache_.remove(req));
      uco.setResult(rset);
      // second, add the new changed object
      cache_.put(req, uco);
    }
  }

  public Object getResult(String req) {

    // if the cache exists and it contains the pattern or sql request
    if (cache_ != null) {
      // return the stored object
      String link = (String) (requests_.get(req));
      if (link == null) {
        // logger.debug("RequestCache:getResult link is null");
        String rsql = getSqlPattern(req);
        RequestCacheObject uco = (RequestCacheObject) (cache_.get(rsql));

        return uco;
      }
      RequestCacheObject uco = (RequestCacheObject) (cache_.get(link));
      if (uco == null) {
        // logger.debug("RequestCache:getResult uco is null");
        return null;
      }
      Object obj = uco.getResult();

      if (obj != null)
        return obj;

    }
    return null;
  }

  public String getSqlPattern(String sql) {
    // try to parse all the cache to determine if the sql statement matches
    // the defined pattern
    if (cache_ != null)
      if (cache_.size() == 0)
        return null;

    for (Enumeration e = cache_.keys(); e.hasMoreElements();) {
      RequestCacheObject uco = (RequestCacheObject) (cache_.get(e
          .nextElement()));

      // if it matches, we return it
      if (uco.getPattern().matcher(sql).matches()) {
        // logger.debug("RequestCache:getSqlPattern yes, it matches
        // req=<"+sql+">");
        return uco.getRequest();
      }
    }
    return null;
  }

  /**
   * make the link between a application request (sql) and the pattern found
   * in the key of the cache_ object
   *
   * @param pattern :
   *            may be "null" String
   */
  public void setLink(String sql, String pattern) {

    if (cache_ != null)
      if (cache_.size() != 0)
        if ((requests_ != null) && (sql != null) && (pattern != null)) {
          requests_.put(sql, pattern);
        }
  }

  public synchronized void reset() {
    // we need to remove all elements in cache
    for (Enumeration e = cache_.keys(); e.hasMoreElements();) {
      RequestCacheObject uco = (RequestCacheObject) (cache_.get(e
          .nextElement()));
      uco.close();
      uco = null;
    }

    // and now, to create again all elements from the configuration file
    cache_.clear();
    cache_ = null;
    cache_ = new Hashtable();
    requests_.clear();
    requests_ = null;
    requests_ = new Hashtable();
    readConfigurationFile();
  }

  public String toString() {
    StringBuffer sbuf = new StringBuffer();
    sbuf.append("=== DUMP REQUESTS ===\n");
    for (Enumeration e = requests_.keys(); e.hasMoreElements();) {
      String s = (String) e.nextElement();
      sbuf.append("key=<" + s + "> value=<" + (String) requests_.get(s)
          + ">\n");
    }
    sbuf.append("=== DUMP CACHE ===\n");
    for (Enumeration e = cache_.keys(); e.hasMoreElements();) {
      String s = (String) e.nextElement();
      RequestCacheObject uco = (RequestCacheObject) cache_.get(s);
      sbuf.append("key(pattern)=<" + s + "> value(RequestCacheObject)=<"
          + uco.toString() + ">\n");
    }
    return sbuf.toString();
  }
}
TOP

Related Classes of org.enhydra.jdbc.util.RequestCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.