Help! My Mind is MUSH

Yep, my mind has turned to a large mushy melon!  I'm working on
creating a CGIDirectoryResource and a PassCGIDirectory that will work
as the equivalent of NCSA ScriptAlias directive.  So far, it is going
well.  I have created a CGIDirectoryResource which extends the
DirectoryResource.  I rewrote/shadowed the createDefaultResource
method to create a new CGIDirectoryResource or a new CgiResource.   It
works just great!  I can create the PassCGIDirectory and have it point
to my old cgi-bin directory and all of the CGIs are usable.

So you ask "What's the problem?".  The current way is that in
DirectoryResource there is a method 'createDefaultResource'.  In it,
indexer.createResource is invoked.  indexer.createResource checks to
see if the new file is a directory or a file.  If it is a directory,
then createDirectoryResource is called.  If it is a file, then
createFileResource is called.  createFileResource creates a new
resource by matching the filename extension with existing defined
extensions. (Shouldn't that be a hash lookup instead of a for loop?)
When it matches, it gets a template of the resource matching the
extension and clones the template into a nice resource.

Well the manor that I am creating the CGIResource is a lobotamized
version of the createFileResource method which creates a new file
resource based on the extension of the file.  I have added a "cgi"
extension that is a template for the CgiResource.  If the "cgi"
extension does not exist, then I get a null returned (Duhh).  I want
to be able to create a new CgiResource, but I can not find the
constructor for the CgiResource class.  Is the compiler creating one
by default?  Should I be doing this some other way?  I just KNOW that
the way that I am doing it is not the best way.  Below is the code
that I wrote.

Any help will be gratefully accepted.

----
// CGIDirectoryResource.java

package w3c.jigsaw.resources ;

import java.io.* ;
import java.util.* ;

import w3c.tools.sorter.*;
import w3c.jigsaw.http.* ;
import w3c.jigsaw.indexer.* ;
import w3c.jigsaw.html.* ;
import w3c.jigsaw.resources.* ;
import w3c.www.http.*;

/**
 * A simple, and reasonably efficient CGI directory resource.
 * This directory resource embeds its own resource store object to keep
 * track of its next children (wich might themselves be CGIDirectoryResource). It
 * is reasonably efficient in the sense that it won't overload the memory with 
 * unused informations. However, stay tuned for a <em>really</em> efficient
 * file based directory resource (tuned to serve only files).
 */


public class CGIDirectoryResource extends DirectoryResource
{

    /**
     * Return the class (if any) that our store defines for given extension.
     * @param ext The extension we want a class for.
     * @return A Class instance, or <strong>null</strong>.
     */

    protected HTTPResource getTemplateFor(String ext) {
		// Try building a default resource for it:
		ResourceIndexer indexer = getServer().getIndexer() ;
		
		HTTPResource template = indexer.loadExtension(ext) ;
		if ( template != null ) {
			HTTPResource check = new HTTPResource();
			if (template.getClass() == check.getClass())
				template = null;
		}
		return template;
    }

    /**
     * Merge the attributes this extension defines, with the provided ones.
     * @param attrs The attributes we want to fill with default values.
     * @param ext The extension name.
     * @param into The already built set of default values.
     * @return A Hashtable, containing the augmented set of default attribute
     *    values.
     */

    protected Hashtable mergeDefaultAttributes(HTTPResource template
					       , String ext
					       , Hashtable into) {
		// Try building a default resource for it:
		ResourceIndexer indexer = getServer().getIndexer() ;
		
		Attribute    attrs[] = template.getAttributes();
		HTTPResource e       = indexer.loadExtension(ext) ;
		if ( e != null ) {
			for (int i = 0 ; i < attrs.length ; i++) {
				if ( ! template.definesAttribute(i) ) {
					int idx = e.lookupAttribute(attrs[i].getName());
					if ( idx >= 0 ) {
						Object value = e.getValue(idx, null);
						if ( value != null )
							into.put(attrs[i].getName(), value) ;
					}
				}
			}
		}
		return into ;
    }

    /**
     * Create a default CGI file resource for this file (that exists).
     * @param directory The directory of the file.
     * @param name The name of the file.
     * @param defs A set of default attribute values.
     * @return An instance of HTTPResource, or <strong>null</strong> if
     *    we were unable to create it.
     */

    protected HTTPResource createCGIFileResource(File directory
												 , String name
												 , Hashtable defs) {
		File         file     = new File(directory, name) ;
		HTTPResource template = null;
		String file_type = "cgi";

		template = getTemplateFor(file_type);

		if ( template == null )
			return null ;
		// Create the runtime-time default values for attributes.
		if ( defs == null )
			defs = new Hashtable(5) ;
		defs.put("directory", directory) ;
		defs.put("identifier", name) ;
		// Merge with values defined by the extension:
		defs = mergeDefaultAttributes(template, file_type, defs) ;
		// Create, initialize and return the new resouce
		try {
			return (HTTPResource) template.getClone(defs);
		} catch (Exception ex) {
			ex.printStackTrace() ;
			return null ;
		}
    }

    /**
     * Try creating a default resource having the given name.
     * This method will make its best effort to create a default resource
     * having this name in the directory. If a file with this name exists,
     * it will check the pre-defined admin extensions and look for a match.
     * If a directory with this name exists, and admin allows to do so, it
     * will create a sub-directory resource.
     * @param name The name of the resource to try to create.
     * @return A Resource instance, if possible, <strong>null</strong>
     *    otherwise.
     */

    public synchronized HTTPResource createDefaultResource(String name) {

		HTTPResource resource;
		
		// Don't automagically create resources of name '..' or '.'
		if (name.equals("..") || name.equals("."))
			return null ;
		// Try building a default resource for it:
		ResourceIndexer indexer = getServer().getIndexer() ;
		// Is there a file with such a name ?
		File file = new File(getDirectory(), name) ;
		if ( ! file.exists() )
			return null ;
		// If the file system is not case sensitive, emulate it :-(
		if ( getServer().checkFileSystemSensitivity() ) {
			File directory = getDirectory();
			if ( directory == null )
				return null;
			String  files[] = directory.list();
			boolean found   = false;
			for (int i = 0 ; i < files.length ; i++) {
				if (found = files[i].equals(name))
					break;
			}
			if ( ! found )
				return null;
		}
		// Prepare a set of default parameters for the resource:
		acquireChildren() ;
		Hashtable defs = new Hashtable(10) ;
		defs.put("parent", this);
		defs.put("resource-store", children) ;
		defs.put("server", getServer()) ;
		defs.put("url", getURL() + name);

		// Okay, dispatch on wether it is a file or a directory.
		if ( file.isDirectory() )
			resource = indexer.createResource(getDirectory(), name, defs) ;
		else
			resource = createCGIFileResource(getDirectory(), name, defs) ;

		if ( resource != null ) {
			// Register this child in our store:
			children.addResource(resource) ;
			// Update or create any relevant negotiable resource:
			if ( getNegotiableFlag() ) 
				updateNegotiableResource(name) ;
			markModified() ;
		}
		return resource ;
    }


}

-- 
---
Brian Millett                    
Technology Applications Inc.     "Heaven can not exist,
(314) 530-1981                          If the family is not eternal"
bpm@techapp.com                   F. Ballard Washburn

Received on Monday, 11 November 1996 14:22:56 UTC