// ServletDirectoryFrame.java
// $Id: ServletDirectoryFrame.java,v 1.15 1998/06/08 08:52:38 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.servlet;

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

import javax.servlet.*;

import org.w3c.jigsaw.http.*;
import org.w3c.util.*;
import org.w3c.tools.resources.store.*;
import org.w3c.tools.resources.*;
import org.w3c.jigsaw.frames.*;

/**
 *  @author Alexandre Rafalovitch <alex@access.com.au>
 *  @author Anselm Baird-Smith <abaird@w3.org>
 *  @author Benoit Mahe <bmahe@w3.org>
 */

public class ServletDirectoryFrame extends HTTPFrame {

    /**
     * The servlet Context.
     */
    protected JigsawServletContext servletContext = null;

    /**
     * The Session Context.
     */
    protected JigsawHttpSessionContext sessionContext = null;

    /**
     * Register the resource and add ServletProperties in httpd.
     * @param resource The resource to register.
     */
    public void registerResource(FramedResource resource) {
	super.registerResource(resource);
	if (getServletProps() == null ) {
	    synchronized (this.getClass()) {
		httpd s = (httpd) getServer();
		if ( s != null ) {
		    // Register the CVS property sheet if not done yet:
		    ObservableProperties props = s.getProperties() ;
		    s.registerPropertySet(new ServletProps(s));
		}
	    }
	}
    }

    /**
     * ServletContext implementation - Lookup a given servlet.
     */

    public Servlet getServlet(String name) {
	if (dresource != null) {
	    ResourceReference rr = dresource.lookup(name);
	    try {
		Resource resource = rr.lock();
		if (resource instanceof ServletWrapper)
		    return ((ServletWrapper) resource).getServlet();
	    } catch (InvalidResourceException ex) {
		return null;
	    } finally {
		rr.unlock();
	    }
	}
	return null;
    }

    /**
     * ServletContext implementation - Enumerate all servlets within context.
     */

    public Enumeration getServlets() {
	if (dresource != null)
	    return new ServletEnumeration(this, 
				  dresource.enumerateResourceIdentifiers());
	else
	    return new ServletEnumeration(this, null);
    }

    /**
     * ServletContext implementation - Enumerate all servlets names
     * within context.
     */

    public Enumeration getServletNames() {
	if (dresource != null)
	    return new ServletNamesEnumeration(this, 
			       dresource.enumerateResourceIdentifiers());
	else
	    return new ServletNamesEnumeration(this, null);
    }

    /**
     * ServletContext implementation - Get server informations.
     */

    public String getServerInfo() {
	return resource.getServer().getSoftware();
    }

    /**
     * ServletContext implementation - Get an attribute value.
     * We map this into the ServletWrapper attributes, without
     * support for name clashes though.
     * @param name The attribute name.
     */

    public Object getAttribute(String name) {
	if ( definesAttribute(name) )
	    return getValue(name, null);
	else if (resource.definesAttribute(name))
	    return resource.getValue(name, null);
	return null;
    }

    protected JigsawHttpSessionContext getJigsawHttpSessionContext() {
	ServletProps sprops = getServletProps();
	if (sprops != null)
	    return sprops.getSessionContext();
	return null;
    }

    protected ServletProps getServletProps() {
	httpd server = (httpd) getServer();
	return (ServletProps)
	    server.getPropertySet(ServletProps.SERVLET_PROPS_NAME);
    }

    /**
     * We add a <em>context</em> attribute to all our children.
     * The <em>context</em> attribute is any object implementing the
     * ServletContext interface.
     */

    protected void updateDefaultChildAttributes(Hashtable attrs) {
	if (servletContext == null)
	    servletContext = 
		new JigsawServletContext(getFrameReference(),
					 getServer().getProperties());
	if (sessionContext == null)
	    sessionContext = getJigsawHttpSessionContext();
	attrs.put("servlet-context", servletContext);
	attrs.put("session-context", sessionContext);
    }

}
