Package org.tamacat.groovy

Source Code of org.tamacat.groovy.ClasspathGroovyLoader

/*
* Copyright (c) 2010, TamaCat.org
* All rights reserved.
*/
package org.tamacat.groovy;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Properties;
import java.util.Set;

import org.codehaus.groovy.control.CompilationFailedException;
import org.tamacat.util.ClassUtils;
import org.tamacat.util.PropertyUtils;
import org.tamacat.util.ResourceNotFoundException;
import org.tamacat.util.StringUtils;

/**
* <p>GroovyClassLoader find the Groovy script in CLASSPATH.
*/
public class ClasspathGroovyLoader extends ClassLoader {
 
  static final String GROOVY_LOADER_CONFIG = "groovyloader.properties";
  static final String CLASSLOADER_CONFIG = "org.tamacat.groovy.groovyloader.properties";
 
  private GroovyClassLoader loader; //delegate ClassLoader
 
  private long checkInterval = 10000; //10sec
 
  private GroovyClassCache cache; //internal class cache
 
  /**
   * <p.default constructor
   */
  public ClasspathGroovyLoader() {
    this(new GroovyClassLoader());
  }
 
  /**
   * <p>Constructor for custom GroovyClassLoader uses.
   * @param loader GroovyClassLoader
   */
  public ClasspathGroovyLoader(GroovyClassLoader loader) {
    this.loader = loader;
    Properties props = null;
    int maxClasses = 1000; //default
    long cacheExpireTime = 3600000; //default 60min
    try {
      props = PropertyUtils.getProperties(GROOVY_LOADER_CONFIG);
    } catch (ResourceNotFoundException e) {
      props = PropertyUtils.getProperties("org.tamacat.groovy." + GROOVY_LOADER_CONFIG);
    }
    if (props != null) {
      checkInterval = StringUtils.parse(props.getProperty("check_interval"),checkInterval);
      maxClasses = StringUtils.parse(props.getProperty("max_classes"),maxClasses);
      cacheExpireTime = StringUtils.parse(props.getProperty("cache_expire_time"),cacheExpireTime);
    }
    cache = new GroovyClassCache(maxClasses);
    cache.setCacheExpireTime(cacheExpireTime);
  }

    /**
     * <p>Loads a class from a file path or class name(FQCN).
     *
     * @throws CompilationFailedException if compilation was not successful
     */
  public synchronized Class<?> loadClass(final String name) {
    try {
      String fileName = getFileName(name);
      GroovyFile groovyFile = cache.get(fileName);
     
      if (groovyFile == null) {
        groovyFile = parseClass(fileName);
      } else {
        if (checkUpdate(groovyFile)) {
          groovyFile = parseClass(fileName, groovyFile);
        }
      }
      if (groovyFile != null){
        cache.put(fileName, groovyFile);
        return groovyFile.getType();
      } else {
        //parent
        if (name.endsWith(".groovy")) return null;
        else return loader.getParent().loadClass(name);
      }
    } catch (Exception e) {
      throw new GroovyClassLoaderException(e);
    }
  }
 
  public synchronized void recompile() {
    Set<String> keys = cache.keySet();
    for (String key : keys) {
      GroovyFile file = cache.get(key);
      Class<?> type = file.getType();
      recompile(type.getName());
    }
  }
 
  public synchronized void recompile(String className) {
    try {
      String fileName = className.replace(".groovy","").replace(".","/") + ".groovy";
      parseClass(fileName);
    } catch (Exception e) {
      throw new GroovyClassLoaderException(e);
    }
  }
 
  public void clearCache() {
    cache.clear();
  }
 
    /**
     * <p>Parses the given file name a Java class capable of being run
     *
     * @param fileName (FQCN)
     * @param groovyFile cashed GroovyFile object.
     *        if groovyFile is null, then create a new GroovyFile instanse.
     * @return GroovyFile (Meta file)
     */
  private GroovyFile parseClass(String fileName, GroovyFile groovyFile) throws Exception {
    URL url = ClassUtils.getURL(fileName);
    if (url == null) return groovyFile;
    File file = getGroovyFile(url);
    long lastModified = file.lastModified();
    if (groovyFile == null || groovyFile.isUpdate(lastModified)) {
      GroovyCodeSource source = new GroovyCodeSource(file);
      source.setCachable(false); //cache disabled
      Class<?> c = loader.parseClass(source, false); //cache disabled
      if (c != null) {
        groovyFile = new GroovyFile(c, lastModified);
      }
    }
    return groovyFile;
  }
 
    /**
     * <p>Parses the given file name a Java class capable of being run
     *
     * @param fileName (FQCN)
     * @return GroovyFile (Meta file)
     */
  private GroovyFile parseClass(String fileName) throws Exception {
    return parseClass(fileName, null);
  }
 
  private File getGroovyFile(URL url) throws URISyntaxException {
    loader.addURL(url);
    File file = new File(url.toURI());
    return file;
  }
 
  private boolean checkUpdate(GroovyFile f) {
    return System.currentTimeMillis() - f.getCreateTime() > checkInterval;
  }
 
  private String getFileName(String name) {
    String fileName = name.replaceFirst("^/", "");
    if (name.endsWith(".groovy")) {
      fileName = fileName.replaceFirst(".groovy$", "").replace(".", "/") + ".groovy";
    } else {
      fileName = fileName.replace(".", "/") + ".groovy";
    }
    return fileName;
  }
}
TOP

Related Classes of org.tamacat.groovy.ClasspathGroovyLoader

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.