📄 resourcestoremanager.java
字号:
// Resourcestoremanager.java// $Id: ResourceStoreManager.java,v 1.29 2003/02/28 10:32:21 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.tools.resources.store ;import org.w3c.tools.resources.AttributeHolder;import org.w3c.tools.resources.InvalidResourceException;import org.w3c.tools.resources.Resource;import org.w3c.tools.resources.ResourceContext;import org.w3c.tools.resources.ResourceReference;import org.w3c.tools.resources.ResourceSpace;import org.w3c.tools.resources.ServerInterface;import org.w3c.tools.resources.SpaceEntry;import org.w3c.tools.resources.serialization.Serializer;import org.w3c.tools.resources.event.ResourceEventQueue;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileInputStream;import java.io.FileReader;import java.io.FilenameFilter;import java.io.FileOutputStream;import java.io.OutputStreamWriter;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.PrintStream;import java.io.Reader;import java.io.Serializable;import java.io.Writer;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.w3c.util.AsyncLRUList;import org.w3c.util.LRUAble;import org.w3c.util.LRUList;import org.w3c.util.Status;class Reference implements ResourceReference { public static boolean debug = false; // Our entry StoreEntry entry = null; // The resource identifier String identifier = null; // The default attributs Hashtable defs = null; public void updateContext(ResourceContext ctxt) { if (defs != null) defs.put("context", ctxt); } /** * The lock count associated to the reference. */ protected int lockCount = 0; public int nbLock() { return lockCount; } protected void invalidate() { entry = null; } protected boolean isValid() { return ( entry != null ) ; } public Resource unsafeLock() throws InvalidResourceException { return lock(); } /** * Lock that reference in memory. * @return A pointer to the underlying resource, after lock succeed. */ public synchronized Resource lock() throws InvalidResourceException { lockCount++; if (entry == null) throw new InvalidResourceException(identifier, "This reference was invalidate"); ResourceStore store = entry.getStore(); Resource resource = store.lookupResource(identifier); if (debug) { if (defs.get("context") == null) System.out.println("**** Context null for : "+identifier); else if (((ResourceContext)(defs.get("context"))).getServer() == null) System.out.println("**** Server null for "+ identifier+"'s context"); } if (resource == null) { resource = store.loadResource(identifier, defs); } if (debug) System.out.println("[LOCK] locking ["+lockCount+"]: "+identifier); return resource; } /** * Unlock that resource reference. */ public void unlock() { lockCount--; if (debug) System.out.println("[LOCK] unlocking ["+lockCount+"]: "+ identifier); } /** * Is that resource locked ? * @return A boolean, <strong>true</strong> if the resource is locked. */ public boolean isLocked() { return lockCount != 0; } Reference (StoreEntry entry, String identifier, Hashtable defs) { this.entry = entry; this.identifier = identifier; this.defs = defs; }}class StoreEntry implements LRUAble, Serializable { boolean istransient = false; // our key in the cache. Integer key = null; // LRU management infos: transient LRUAble next = null ; transient LRUAble prev = null ; // ResourceStore infos: transient ResourceStore store = null ; // References transient Hashtable references = null; //The manager transient ResourceStoreManager manager = null; String repository = null ; transient File rep = null; public File getRepository() { if (rep == null) rep = new File(manager.storedir, repository); return rep; } public LRUAble getNext() { return next; } public LRUAble getPrev() { return prev; } public void setNext(LRUAble next) { this.next = next; } public void setPrev(LRUAble prev) { this.prev = prev; } public void setTransient(boolean onoff) { istransient = onoff; } public boolean isTransient() { return istransient; } /** * Load the store of this entry. */ synchronized ResourceStore getStore() { if ( store == null ) { store = new ResourceStoreImpl() ; store.initialize(manager, this, getRepository(), manager.serializer) ; manager.incrLoadedStore(); } return store; } /** * Delete the store of this entry */ synchronized void deleteStore() { Enumeration enum = references.elements(); Reference rr = null; while (enum.hasMoreElements()) { rr = (Reference)enum.nextElement(); rr.invalidate(); } getRepository().delete(); if (store != null) { store = null; manager.decrLoadedStore(); } references = null; } /** * Lookup this resource. * @param identifier The resource identifier. * @return A Resource instance, or <strong>null</strong> if either the * resource doesn't exist, or it isn't loaded yet. */ public ResourceReference lookupResource (String identifier) { return (ResourceReference)references.get(identifier); } /** * Load a resource, or get one from the cache. * @param identifier The resource identifier. * @return A Resource instance, or <strong>null</strong> if the resource * doesn't exist in that storeEntry. * @exception InvalidResourceException If the resource couldn't be * restored from its pickled format. */ synchronized ResourceReference loadResource(String name, Hashtable defs) { ResourceReference rr = lookupResource(name); if (rr != null) return rr; rr = new Reference(this, name, defs); try { Resource res = rr.lock(); if (res == null) return null; } catch (InvalidResourceException ex) { return null; } finally { rr.unlock(); } references.put(name, rr); return rr; } /** * Save a given resource. * @param resource The resource to be save right now. */ synchronized void saveResource(Resource resource) { getStore(); store.saveResource(resource); } /** * Add a new resource to the resource store. * @param resource The resource to add. */ synchronized ResourceReference addResource(Resource resource, Hashtable defs) { getStore(); store.addResource(resource); String name = resource.getIdentifier(); ResourceReference rr = new Reference(this, name , defs); references.put(name, rr); return rr; } /** * FIXME doc */ public synchronized void markModified(Resource resource) { getStore(); store.markModified(resource); } /** * Rename a resource in this resource store. * @param identifier The identifier of the resource to be renamed. */ public synchronized void renameResource(String oldid, String newid) { getStore(); store.renameResource(oldid, newid); Reference rr = (Reference)lookupResource(oldid); if (rr != null) { rr.identifier = newid; references.remove(oldid); references.put(newid, rr); } } public synchronized Enumeration enumerateResourceIdentifiers() { getStore(); return store.enumerateResourceIdentifiers(); } /** * Remove a resource from this resource store. * @param identifier The identifier of the resource to be removed. */ public synchronized void removeResource(String identifier) { getStore(); Reference rr = (Reference)references.get(identifier); if (rr != null) { references.remove(identifier); manager.getEventQueue().removeSourceEvents(rr); rr.invalidate(); } store.removeResource(identifier); } /** * Try unloading the space for this entry. */ synchronized boolean unloadStore() { if ( store != null ) { Enumeration enum = references.elements(); ResourceReference rr = null; while (enum.hasMoreElements()) { rr = (ResourceReference)enum.nextElement(); if (rr.isLocked()) return false; } // Will the store unload itself ? if ( ! store.acceptUnload()) return false; // Great, proceed: shutdownStore(); } return true; } /** * Shutdown the store. */ synchronized void shutdownStore() { if ( store != null ) { store.shutdown() ; store = null ; references = new Hashtable(); // clear also the references manager.decrLoadedStore(); } } /** * Try stabilizing the store. */ synchronized void saveStore() { if ( store != null ) { // Save the resource store: store.save(); } } void initialize(ResourceStoreManager manager) { this.manager = manager; this.references = new Hashtable(); } StoreEntry(ResourceStoreManager manager, String repository, Integer key) { this.manager = manager; this.store = null ; this.repository = repository ; this.key = key; this.references = new Hashtable(); } StoreEntry(ResourceStoreManager manager, File repository, Integer key) { this.manager = manager; this.store = null ; this.rep = repository ; this.key = key; this.references = new Hashtable(); }}class StoreManagerSweeper extends Thread { ResourceStoreManager manager = null ; boolean killed = false ; protected synchronized void waitEvent() { boolean done = false ; // Wait for an event to come by: while ( ! done ) { try { wait() ; done = true ; } catch (InterruptedException ex) { } } } protected synchronized void sweep() { notifyAll() ; } protected synchronized void shutdown() { killed = true ; notifyAll() ; } public void run() { while ( true ) { waitEvent() ; // The whole trick is to run the collect method of the store // manager, without having the lock on the sweeper itself, so // that clients can still trigger it later if ( killed ) { break ; } else { try { manager.collect() ; } catch (Exception ex) { // We really don't want this thread to die ex.printStackTrace() ; } } } } StoreManagerSweeper(ResourceStoreManager manager) { this.manager = manager ; this.setName("StoreSweeper") ; this.start() ; }}public class ResourceStoreManager implements ResourceSpace { /** * Number of sub-levels file system directories in the store directory. */ public final static int SUBDIRS = 128; public static final String ROOT_REP = "root.xml"; public static final String STATE_F = "state.xml"; public boolean debugMemory = false; protected Serializer serializer = null; /** * The loaded resource stores entries. */ Hashtable entries = new Hashtable(256); // <sentryKey - StoreEntry> /** * The limit of "BIG" stores, over this limits stores will be kept * in memory for performance purposes * If set to -1, this optimization won't happen */ private int storeSizeLimit = -1; /** * The max number of loaded stores */ private int maxLoadedStore = -1; /** * The number of loaded stores
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -