-// FIXME
+// FIXEME
// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
package org.xwt;
/** Base class for XWT resources */
public abstract class Res extends JS {
+ /** return a resource for a given url */
+ public static final Res fromURL(String url) throws JSExn {
+ if (url.startsWith("http://")) return new Res.HTTP(url);
+ else if (url.startsWith("https://")) return new Res.HTTP(url);
+ else if (url.startsWith("data:")) return new Res.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Res.ByteArray(url.substring(5).getBytes(), null);
+ throw new JSExn("invalid resource specifier " + url);
+ }
+
// Base Class //////////////////////////////////////////////////////////////////////
public String typeName() { return "resource"; }
public Res addExtension(String extension) { return new Ref(this, extension); }
- public Object get(Object key) {
+ public Object get(Object key) throws JSExn {
if ("".equals(key)) {
try {
Template t = Template.getTemplate(addExtension(".xwt"));
- return t == null ? null : t.getStatic();
+ return t == null ? null : t.getStatic(null); /** FIXME VERY BAD! */
} catch (Exception e) {
- Log.log(this, e);
+ Log.info(this, e);
return null;
}
}
public InputStream getInputStream(String path) throws IOException {
CachedInputStream cis = (CachedInputStream)cachedInputStreams.get(path);
if (cis == null) {
- java.io.File f = null;
if (disk) {
- f = new java.io.File(System.getProperty("user.home") +
- java.io.File.separatorChar + ".xwt" +
- java.io.File.separatorChar + "caches" +
- java.io.File.separatorChar +
- new String(Base64.encode(key.getBytes())));
- Log.log(this, "caching resource in " + f);
- new java.io.File(f.getParent()).mkdirs();
+ java.io.File f = LocalStorage.Cache.getCacheFileForKey(key);
if (f.exists()) return new FileInputStream(f);
+ cis = new CachedInputStream(parent.getInputStream(path), f);
+ } else {
+ cis = new CachedInputStream(parent.getInputStream(path));
}
- cis = new CachedInputStream(parent.getInputStream(path), f);
cachedInputStreams.put(path, cis);
}
return cis.getInputStream();
public InputStream getInputStream(String path) throws IOException { return parent.getInputStream("/" + key + path); }
}
+ /** provides redirection of a specified key */
+ public static class Graft extends Res {
+ Res graftee;
+ Object replaced_key, replaced_val;
+ Graft(Res graftee, Object key, Object val) { this.graftee = graftee; this.replaced_key = key; this.replaced_val = val; }
+ public boolean equals(Object o) { return this == o || graftee.equals(o); }
+ public int hashCode() { return graftee.hashCode(); }
+ public InputStream getInputStream(String s) throws IOException { return graftee.getInputStream(s); }
+ public Object get(Object key) throws JSExn { return replaced_key.equals(key) ? replaced_val : graftee.get(key); }
+ public Object callMethod(Object name, Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ if (replaced_key.equals(name)) {
+ if (replaced_val instanceof JS) return ((JS)replaced_val).call(a, b, c, rest, nargs);
+ else throw new JSExn("attempted to call non-function (class="+replaced_val.getClass()+")");
+ } else {
+ return graftee.callMethod(name, a, b, c, rest, nargs);
+ }
+ }
+ public Number coerceToNumber() { return graftee.coerceToNumber(); }
+ public String coerceToString() { return graftee.coerceToString(); }
+ public boolean coerceToBoolean() { return graftee.coerceToBoolean(); }
+ public String typeName() { return graftee.typeName(); }
+ }
+
/** shadow resource which replaces the graft */
public static class ProgressWatcher extends Res {
final Res watchee;