/src/sys/java/fanx/util/EnvScripts.java
Java | 156 lines | 93 code | 27 blank | 36 comment | 24 complexity | c3016bf4fa1a8ed5834c746dc1efb1b6 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- //
- // Copyright (c) 2008, Brian Frank and Andy Frank
- // Licensed under the Academic Free License version 3.0
- //
- // History:
- // 10 Mar 08 Brian Frank Creation
- //
- package fanx.util;
- import java.util.HashMap;
- import fan.sys.*;
- /**
- * EnvScripts manages caching and compilation of 'Env.compileScript'.
- */
- public class EnvScripts
- {
- //////////////////////////////////////////////////////////////////////////
- // Public
- //////////////////////////////////////////////////////////////////////////
- public Type compile(File file, Map options)
- {
- // normalize the file path as our cache key
- file = file.normalize();
- // unless force=true, check the cache
- if (!getOption(options, "force", false))
- {
- CachedScript c = getCache(file);
- // if cached, try to lookup type (it might have been GCed)
- if (c != null)
- {
- Type t = Type.find(c.typeName, false);
- if (t != null) return t;
- }
- }
- // generate a unique pod name
- String podName = generatePodName(file);
- // compile the script
- Pod pod = compile(podName, file, options);
- // get the primary type
- List types = pod.types();
- Type t = null;
- for (int i=0; i<types.sz(); ++i)
- {
- t = (Type)types.get(i);
- if (t.isPublic()) break;
- }
- if (t == null)
- throw Err.make("Script file defines no public classes: " + file);
- // put it into the cache
- putCache(file, t);
- return t;
- }
- //////////////////////////////////////////////////////////////////////////
- // Utils
- //////////////////////////////////////////////////////////////////////////
- private String generatePodName(File f)
- {
- String base = f.basename();
- StringBuilder s = new StringBuilder(base.length()+6);
- for (int i=0; i<base.length(); ++i)
- {
- int c = base.charAt(i);
- if ('a' <= c && c <= 'z') { s.append((char)c); continue; }
- if ('A' <= c && c <= 'Z') { s.append((char)c); continue; }
- if (i > 0 && '0' <= c && c <= '9') { s.append((char)c); continue; }
- }
- synchronized (counterLock) { s.append('_').append(counter++); }
- return s.toString();
- }
- private Pod compile(String podName, File f, Map options)
- {
- // use Fantom reflection to run compiler::Main.compileScript(File)
- Method m = Slot.findMethod("compiler::Main.compileScript", true);
- return (Pod)m.call(podName, f, options);
- }
- //////////////////////////////////////////////////////////////////////////
- // CachedScript
- //////////////////////////////////////////////////////////////////////////
- CachedScript getCache(File file)
- {
- synchronized (cache)
- {
- // check cache
- String key = cacheKey(file);
- CachedScript c = (CachedScript)cache.get(key);
- if (c == null) return null;
- // check that timestamp and size still the same
- if (OpUtil.compareEQ(c.modified, file.modified()) &&
- OpUtil.compareEQ(c.size, file.size()))
- return c;
- // nuke from cache
- cache.remove(key);
- return null;
- }
- }
- void putCache(File file, Type t)
- {
- CachedScript c = new CachedScript();
- c.modified = file.modified();
- c.size = file.size();
- c.typeName = t.qname();
- synchronized (cache) { cache.put(cacheKey(file), c); }
- }
- String cacheKey(File f)
- {
- return f.toStr();
- }
- static class CachedScript
- {
- DateTime modified;
- long size;
- String typeName;
- }
- //////////////////////////////////////////////////////////////////////////
- // Option Utils
- //////////////////////////////////////////////////////////////////////////
- static boolean getOption(Map options, String key, boolean def)
- {
- if (options == null) return def;
- Boolean x = (Boolean)options.get(key);
- if (x == null) return def;
- return x;
- }
- //////////////////////////////////////////////////////////////////////////
- // Fields
- //////////////////////////////////////////////////////////////////////////
- HashMap cache = new HashMap(300);
- Object counterLock = new Object();
- int counter = 0;
- }