containerresource.java
来自「很棒的web服务器源代码」· Java 代码 · 共 518 行
JAVA
518 行
// ContainerResource.java// $Id: ContainerResource.java,v 1.21 2004/02/10 13:34:44 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.tools.resources ;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import org.w3c.tools.resources.event.Events;import org.w3c.tools.resources.event.StructureChangedEvent;import org.w3c.tools.resources.store.ResourceStoreManager;/** * This resource manage children resources. */public class ContainerResource extends AbstractContainer { public static boolean debug = false; /** * Attribute index - The index of the resource key. */ protected static int ATTR_KEY = -1; static { Attribute a = null ; Class cls = null ; // Get a pointer to our own class: try { cls = Class.forName("org.w3c.tools.resources.ContainerResource") ; } catch (Exception ex) { ex.printStackTrace() ; System.exit(1) ; } // The identifier attribute: a = new IntegerAttribute("key", null, Attribute.COMPUTED); ATTR_KEY = AttributeRegistry.registerAttribute(cls, a); } public Object getClone(Object values[]) { values[ATTR_KEY] = null; return super.getClone(values); } /** * Get the container Key. This key must be unique and unchanged * during the container life. * @return a String instance. */ public Integer getKey() { Integer key = (Integer) unsafeGetValue(ATTR_KEY, null); if (key == null) { key = new Integer(getIdentifier().hashCode() ^ (new Date().hashCode())); if (debug) { System.out.println("*** new key is: " + key); } ResourceStoreManager rsm = getServer().getResourceStoreManager(); while (!rsm.checkKey(key)) {// key = new Integer (key.intValue() ^ (int) Math.random()); key = new Integer ((int)((1.9 *(Math.random()-0.5)) * Integer.MAX_VALUE)); if (debug) { System.out.println("*** updated key is: " + key); } } setValue(ATTR_KEY, key); } return key; } protected SpaceEntry getSpaceEntry() { ResourceReference rr = getParent(); if (rr == null) //I'm root or external!! return new SpaceEntryImpl(this); try { //FIXME sure that is a containerResource? ContainerResource cont = (ContainerResource) rr.lock(); return new SpaceEntryImpl(cont); } catch (InvalidResourceException ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); return null; } finally { rr.unlock(); } } /** * Get the SpaceEntry of our children resources. * @return A SpaceEntry instance. */ protected SpaceEntry getChildrenSpaceEntry() { return new SpaceEntryImpl( this ); } /** * This handles the <code>RESOURCE_MODIFIED</code> kind of events. * @param evt The StructureChangeEvent. */ public void resourceModified(StructureChangedEvent evt) { if (! isUnloaded()) super.resourceModified(evt); } /** * A new resource has been created in some space. * This handles the <code>RESOURCE_CREATED</code> kind of events. * @param evt The event describing the change. */ public void resourceCreated(StructureChangedEvent evt) { if (! isUnloaded()) super.resourceCreated(evt); } /** * A resource is about to be removed * This handles the <code>RESOURCE_REMOVED</code> kind of events. * @param evt The event describing the change. */ public void resourceRemoved(StructureChangedEvent evt) { if (! isUnloaded()) super.resourceRemoved(evt); } /** * Update default child attributes. * A parent can often pass default attribute values to its children, * such as a pointer to itself (the <em>parent</em> attribute). * <p>This is the method to overide when you want your container * to provide these kinds of attributes. By default this method will set * the following attributes: * <dl><dt>name<dd>The name of the child (it's identifier) - * String instance. * <dt>parent<dd>The parent of the child (ie ourself here) - * a ContainerResource instance. * <dt>url<dd>If a <em>identifier</em> attribute is defined, that * attribute is set to the full URL path of the children. * </dl> */ protected ResourceContext updateDefaultChildAttributes(Hashtable attrs) { ResourceContext context = super.updateDefaultChildAttributes(attrs); if (context == null) { context = new ResourceContext(getContext()); attrs.put(co, context) ; } String name = (String) attrs.get(id); if ( name != null ) { StringBuffer sb = new StringBuffer(128); sb.append(getURLPath()); sb.append(java.net.URLEncoder.encode(name)); attrs.put(ur, sb.toString()); } return context; } /** * Enumerate children resource identifiers. * @param all Should all resources be enumerated ? Resources are often * created on demand only, this flag allows the caller to tell the * container about wether it is interested only in already created * resources, or in all resources (even the one that have not yet been * created). * @return An String enumeration, one element per child. */ public synchronized Enumeration enumerateResourceIdentifiers(boolean all) { ResourceSpace space = getSpace(); acquireChildren(); return space.enumerateResourceIdentifiers( getChildrenSpaceEntry() ); } /** * Create a default child resource in that container. * This method is called by the editor to add a default resource * in the container under the given name. The meaning of <em>default</em> * is left up to the container here. * @param name The identifier for the new resource. */ public ResourceReference createDefaultResource(String name) { return null; } /** * Get the number of matching character (case sensitive). * ex getMatchingCharsCount("index.html", "Index.html") = 10. * @param s1 the first string. * @param s2 the second string. * @return -1 if s1 and s2 are not equals (ignoring case), * otherwise the number of matching character (case sensitive). */ protected int getMatchingCharsCount(String s1, String s2) { int len = -1; int matching = 0; if (s1 == null || s2 == null || ((len = s1.length()) != s2.length())) return -1; for (int i=0; i<len; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 == c2) { matching++; continue; } c1 = Character.toUpperCase(c1); c2 = Character.toUpperCase(c2); if (c1 != c2) return -1; } return matching; } /** * Lookup a children in the container. * @param name The name of the children to lookup. */ public ResourceReference lookup(String name) { acquireChildren(); SpaceEntry sp = getChildrenSpaceEntry(); ResourceSpace space = getSpace(); ResourceReference rr = internalLookup(name, sp, space); if ((rr == null) && (! getServer().checkFileSystemSensitivity())) { Enumeration children = space.enumerateResourceIdentifiers(sp); //look for possible matching identifier int max = -1; String realname = null; while (children.hasMoreElements()) { String child = (String)children.nextElement(); int matching = getMatchingCharsCount(name, child); if (matching > max) { max = matching; realname = child; } } if (realname != null) rr = internalLookup(realname, sp, space); } return rr; } protected ResourceReference internalLookup(String name, SpaceEntry sp, ResourceSpace space) { ResourceReference rr = space.lookupResource(sp, name); if (rr != null) return rr; synchronized (this) { rr = space.lookupResource(sp, name); if (rr != null) return rr; Hashtable defs = new Hashtable(5) ; defs.put(id, name); ResourceContext context = updateDefaultChildAttributes(defs); rr = space.loadResource(sp, name, defs); if (rr != null) { context.setResourceReference(rr); try { Resource resource = rr.lock(); if (resource instanceof FramedResource) { FramedResource fres = (FramedResource) resource; fres.addStructureChangedListener(this); // send event } } catch (InvalidResourceException ex) { // nothing here } finally { rr.unlock(); } } } return rr; } /** * Lookup the next component of this lookup state in here. * @param ls The current lookup state. * @param lr The lookup result under construction. * @exception ProtocolException If an error occurs. * @return A boolean, <strong>true</strong> if lookup has completed, * <strong>false</strong> if it should be continued by the caller. */ public boolean lookup(LookupState ls, LookupResult lr) throws ProtocolException { // Give a chance to our super-class to run its own lookup scheme: if ( super.lookup(ls, lr) ) return true; // Perform our own lookup on the next component: String name = ls.getNextComponent() ; ResourceReference rr = null; rr = lookup(name); if (rr == null) { lr.setTarget(null); return false; } try { lr.setTarget(rr); FramedResource resource = (FramedResource) rr.lock(); return (resource != null ) ? resource.lookup(ls, lr) : false; } catch (InvalidResourceException ex) { return false; } finally { rr.unlock(); } } /** * Remove a child resource from that container. * @param name The name of the child to remove. * @exception MultipleLockException If somone else has locked the * resource. */ public void delete(String name) throws MultipleLockException { ResourceReference rr = null; rr = lookup(name); if (rr != null) { try { synchronized (rr) { Resource resource = rr.lock(); if (resource instanceof FramedResource) ((FramedResource)resource). removeStructureChangedListener(this); resource.delete(); } } catch (InvalidResourceException ex) { // FIXME ?? } finally { rr.unlock(); } } } /** * Delete that container and its children if children is true * @exception MultipleLockException If somone else has locked one * of the resource child. */ public synchronized void replace(DirectoryResource newdir) throws MultipleLockException { Enumeration e = enumerateResourceIdentifiers(); ResourceReference rr = null; Resource resource = null; while (e.hasMoreElements()) { rr = lookup((String) e.nextElement()); if (rr != null) { try { resource = rr.lock(); ResourceContext ctxt = new ResourceContext( newdir.getContext()); resource.setContext(ctxt, true); if (resource instanceof FramedResource) { ((FramedResource)resource). removeStructureChangedListener(this); ((FramedResource)resource). addStructureChangedListener(newdir); } } catch (InvalidResourceException ex) { // do nothing , continue } finally { rr.unlock(); } } } super.delete(); } /** * Delete that resource container. * @exception MultipleLockException If somone else has locked the * resource. */ public synchronized void delete() throws MultipleLockException { disableEvent(); ResourceSpace space = getSpace(); //delete our children acquireChildren(); deleteChildren(); disableEvent(); SpaceEntry sentry = getChildrenSpaceEntry(); //delete myself super.delete(); space.deleteChildren(sentry); } protected synchronized void deleteChildren() throws MultipleLockException { disableEvent(); acquireChildren(); Enumeration e = enumerateResourceIdentifiers(); while (e.hasMoreElements()) delete((String)e.nextElement()); enableEvent(); } /** * This resource is being unloaded. * The resource is being unloaded from memory, perform any additional * cleanup required. */ public void notifyUnload() { super.notifyUnload(); // anything else? } protected boolean acquired = false; /** * Acquire our children. Must be called before all child manipulation. */ protected synchronized void acquireChildren() { if (!acquired) { ResourceSpace space = getSpace(); space.acquireChildren( getChildrenSpaceEntry() ); acquired = true; } } /** * Add an initialized resource into this store container instance. * @param resource The resource to be added to the store. */ protected synchronized ResourceReference addResource(Resource resource, Hashtable defs) { acquireChildren(); ResourceReference rr = getSpace().addResource(getChildrenSpaceEntry() , resource, defs); resource.getContext().setResourceReference(rr); if (resource instanceof FramedResource) { FramedResource fres = (FramedResource) resource; fres.addStructureChangedListener(this); } markModified() ; postStructureChangedEvent(rr, Events.RESOURCE_CREATED); return rr; } /** * Initialize and register the given resource within that container. * @param name The identifier for the resource. * @param resource An unitialized resource instance. * @param defs A default set of init attribute values (may be * <strong>null</strong>). * @exception InvalidResourceException If an error occurs during * the registration. */ public void registerResource(String name, Resource resource, Hashtable defs) throws InvalidResourceException { acquireChildren(); // Create a default set of attributes: if ( defs == null ) defs = new Hashtable(4) ; defs.put(id, name); ResourceContext context = updateDefaultChildAttributes(defs); if (context != null) { resource.initialize(defs); ResourceReference rr; rr = getSpace().addResource(getChildrenSpaceEntry(), resource, defs); context.setResourceReference(rr); if (resource instanceof FramedResource) { FramedResource fres = (FramedResource) resource; fres.addStructureChangedListener(this); // send event } markModified(); postStructureChangedEvent(rr, Events.RESOURCE_CREATED); } else { throw new InvalidResourceException(getIdentifier(), name, "unable to get context"); } } /** * Initialize ourself. * As we are a container resource that really contains something, we make * sure our URL ends properly with a slash. * @param values Our default attribute values. */ public void initialize(Object values[]) { super.initialize(values); disableEvent(); // If my URL doesn't end with a slah, correct it: String url = getURLPath() ; if ((url != null) && ! url.endsWith("/") ) setValue(ATTR_URL, url+"/") ; acquired = false; enableEvent(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?