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 + -
显示快捷键?