/** Met dans le cache le résultat de l'url indiquée */ public boolean putInCache(String url) throws Exception { // Lecture MyInputStream in = null; try { in = Util.openStream(url); byte buf[] = in.readFully(); // Nettoyage et Ecriture String id = codage(url); File g = new File(dir + Util.FS + id); g.delete(); RandomAccessFile f = null; try { f = new RandomAccessFile(dir + Util.FS + id, "rw"); f.write(buf); } finally { if (f != null) f.close(); } aladin.trace(3, "Put in cache [" + url + "]"); return true; } catch (Exception e) { if (aladin.levelTrace >= 3) e.printStackTrace(); } finally { if (in != null) in.close(); } return false; }
/** Retourne le stream associé à une URL, d'abord teste le réseau et sinon le cache */ public InputStream getWithBackup(String url) throws Exception { // Cache non accessible, on retourne directement l'appel distant if (!isAvailable()) return Util.openStream(url); Exception eBackup = null; InputStream is = null; // Tentative d'accès direct par le réseau try { is = Util.openStream(url); if (is == null) throw new Exception("cache openStream error"); } catch (Exception e) { is = null; eBackup = e; } String id = codage(url); File f = new File(dir + Util.FS + id); // Ca a marché en direct ! if (is != null) { // Devrais-je tenter de remettre à jour le cache if (!f.isFile() || outOfDate(f)) add(url); return is; } // Ca n'a pas marché en direct, peut être présent dans le cache ? if (f.isFile() && f.canRead() && f.length() > 0) { aladin.trace(3, "[" + url + "] backup from cache !"); return new FileInputStream(f); } // Bon, pas d'autre solution throw eBackup; }
protected Cache(Aladin aladin) { this.aladin = aladin; // Création de $HOME/.aladin/Cache si ce n'est déjà fait if (!aladin.createCache()) return; dir = getCacheDir(); File f = new File(dir); if (!f.isDirectory() && !f.mkdir()) { dir = null; return; } todo = new Vector(); }
/** Met à jour le cache en fonction de la liste todo */ private void updateCache() { aladin.trace(2, "Start cache updater..."); Vector v; synchronized (this) { v = (Vector) todo.clone(); todo.clear(); } Enumeration e = v.elements(); while (e.hasMoreElements()) { String url = (String) e.nextElement(); try { putInCache(url); } catch (Exception e1) { } Util.pause(1000); // Pose entre deux } fin(); }
/** Nettoie le cache */ void clear() { if (!isAvailable()) return; try { cacheLock = true; File cache = new File(dir); String f[] = cache.list(); for (int i = 0; f != null && i < f.length; i++) { // System.out.println("f="+decodage(f[i])); try { (new File(dir + Util.FS + f[i])).delete(); } catch (Exception e1) { e1.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } cacheLock = false; Aladin.trace(3, "Clear cache"); }
/** Retourne le Stream associé à une URL */ public InputStream get(String url) throws Exception { // Cache non accessible, on retourne directement l'appel distant if (!isAvailable()) return Util.openStream(url); String id = codage(url); File f = new File(dir + Util.FS + id); // Présent dans le cache, génial ! if (f.isFile() && f.canRead() && f.length() > 0) { // Devra être mise à jour ? if (outOfDate(f)) add(url); aladin.trace(3, "[" + url + "] read in cache !"); return new FileInputStream(f); } // Absent du cache, on va l'y mettre et appeler à nouveau la méthode if (putInCache(url)) return get(url); // Bon, je n'y arrive pas System.err.println("Caching not available for [" + url + "] !!!"); // return (new URL(url)).openStream(); return Util.openStream(url); }
/** Ajoute une url dans la liste des ressources qu'il faut mettre à jour dans le cache */ private synchronized void add(String url) { aladin.trace(3, "Add [" + url + "] for cache upgrade"); todo.addElement(url); startThread(); }