// VirtualHostFrame.java
// $Id: VirtualHostFrame.java,v 1.8 1999/06/11 16:36:08 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1998.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.frames;

import org.w3c.tools.resources.*;
import org.w3c.jigsaw.http.* ;
import org.w3c.www.http.* ;

/**
 * For Virtual Hosting.
 */
public class VirtualHostFrame extends HTTPFrame {

    /**
     * Attribute index - The default root (for unknown hosts)
     */
    protected static int ATTR_FOLLOWUP = -1;

    static {
	Class     c = null;
	Attribute a = null;

	try {
	    c = Class.forName("org.w3c.jigsaw.frames.VirtualHostFrame");
	} catch (Exception ex) {
	    ex.printStackTrace();
	    System.exit(1);
	}
	// Register our default root:
	a = new StringAttribute("followup"
				, null
				, Attribute.EDITABLE);
	ATTR_FOLLOWUP = AttributeRegistry.registerAttribute(c, a);
    }

    protected ResourceReference followup = null;

    /**
     * Get the name of the resource used as a followup.
     * @return A String giving the name of the resource to be used as the
     * default.
     */

    public String getFollowup() {
	return getString(ATTR_FOLLOWUP, null);
    }

    public void registerResource(FramedResource resource) {
	super.registerOtherResource(resource);
    }

    /**
     * Lookup the followup resource.
     * @return The loaded resource for the current followup.
     */

    public synchronized ResourceReference lookupFollowup() {
	if ( followup == null ) {
	    String name  = getFollowup();
	    if ( name != null ) 
		followup = getServer().loadRoot(name);
	    if ( followup == null ) {
		getServer().errlog(getIdentifier()
				   + "[" + getClass().getName() + "]: "
				   + "unable to restore \"" + name + "\" "
				   + " from root store.");
	    }
	}
	return followup;
    }

    /**
     * Lookup the target resource when associated with an unknown resource.
     * @param ls The current lookup state
     * @param lr The result
     * @return true if lookup is done.
     * @exception ProtocolException If an error relative to the protocol occurs
     */
    protected boolean lookupOther(LookupState ls, LookupResult lr) 
	throws ProtocolException
    {
	// Try to lookup on the host header:
	ResourceReference vrroot = null;
	ContainerResource root = null;
	
	root = (ContainerResource)getResource();
	Request r = (Request)ls.getRequest();
	if ( r != null ) {
	    String  host = r.getHost();
	    String protocol = r.getURL().getProtocol();
	    if ( host != null ) {
		// must strip the port if different from 80!
		if (host.endsWith(":80") && protocol.equals("http"))
		    host = host.substring(0, host.lastIndexOf(":80"));
		// and the same for https (443)
		if (host.endsWith(":443") && protocol.equals("https"))
		    host = host.substring(0, host.lastIndexOf(":443"));
		vrroot = root.lookup(host.toLowerCase());
	    }
	}
	if ( vrroot == null )
	    vrroot  = lookupFollowup();
	// Check for what we got:
	if (vrroot == null)
	    return super.lookupOther(ls, lr);
	try {
	    lr.setTarget(vrroot);
	    FramedResource resource = (FramedResource) vrroot.lock();
	    boolean done = 
	      (resource != null ) ? resource.lookup(ls, lr) : false;
	    if (! done)
	      lr.setTarget(null);
	      // because the vroot eats the lookup state components
	      // we have to return true.
	      // Should not be continued by the caller.
	    return true;
	} catch (InvalidResourceException ex) {
	    return false;
	} finally {
	    vrroot.unlock();
	}
    }
}
