// RelocateResource.java
// $Id: RelocateResource.java,v 1.1 1997/06/09 09:47:21 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.tools.resources.http ;

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

import w3c.tools.resources.*;
import w3c.tools.resources.LookupState;
import w3c.tools.resources.impl.*;
import w3c.tools.resources.indexer.*;

import w3c.tools.store.*;
import w3c.jigsaw.http.*;
import w3c.www.http.*;

/**
 * This resource will always emit a relocation to some given URL.
 */


public class RelocateResource extends HTTPResource {
  /**
   * Name of the state to hold the PATH_INFO in the request.
   */
  public final static 
  String PATH_INFO = "w3c.jigsaw.resources.RelocateResource.PathInfo";

  protected String location = null;

  protected boolean handlePathInfo = false;

  public String getLocation() {
    return (String)holder.protectedGetValue("location");
  }

  public void setLocation(String location) {
    holder.protectedSetValue("location",location);
  }

  public String igetLocation() {
    return location;
  }

  public void isetLocation(String location) {
    this.location = location;
  }

  public boolean getHandlePathInfo() {
    return ((Boolean)
	    holder.protectedGetValue("handlePathInfo")).booleanValue();
  }

  public void setHandlePathInfo(boolean handlePathInfo) {
    holder.protectedSetValue("handlePathInfo", new Boolean(handlePathInfo));
  }

  public boolean igetHandlePathInfo() {
    return handlePathInfo;
  }

  public void isetHandlePathInfo(boolean handlePathInfo) {
    this.handlePathInfo = handlePathInfo;
  }

  public ResourceReference resolve(LookupState state) {
    ResourceReference rr = super.resolve(state);
    if (rr != null) return rr;
    else  if (! igetHandlePathInfo() ) return null;
    // Compute PATH INFO, store it as a piece of state in the request:
    StringBuffer pathinfo = new StringBuffer();
    while ( state.hasMoreComponents() ) {
      pathinfo.append('/');
      pathinfo.append(state.getNextComponent());
    }
    if (state.hasRequest() ) {
      Request request = state.getRequest();
      request.setState(PATH_INFO, pathinfo.toString());
    }
    return self;
  }

//   public boolean lookup(LookupState ls, LookupResult lr) 
//     throws HTTPException
//   {
//     // Perform our super-class lookup strategy:
//     if ( super.lookup(ls, lr) ) {
//       return true;
//     } else if ( ! igetHandlePathInfo() ) {
//       return false;
//     }
//     // Compute PATH INFO, store it as a piece of state in the request:
//     StringBuffer pathinfo = new StringBuffer();
//     while ( ls.hasMoreComponents() ) {
//       pathinfo.append('/');
//       pathinfo.append(ls.getNextComponent());
//     }
//     if (ls.hasRequest() ) {
//       Request request = ls.getRequest();
//       request.setState(PATH_INFO, pathinfo.toString());
//     }
//     lr.setTarget(this);
//     return true;
//   }
	
  /**
   * Emit a redirect.
   * All GET requests are redirected toward the target location.
   * @param client The client issuing the request.
   * @param request The request to handle.
   * @exception HTTPException If the request couldn't be handled.
   */

  public Reply get (Request request)
    throws HTTPException
  {
    String location = getLocation() ;
    if ( location == null ) {
      Reply error = request.makeReply(HTTP.INTERNAL_SERVER_ERROR) ;
      error.setContent("The target RelocateResource doesn't define the"
		       + " relocation location. The server is "
		       + " misconfigured.") ;
      throw new HTTPException(error) ;
    } else {
      Reply  reply    = request.makeReply(HTTP.MOVED_TEMPORARILY) ;
      URL    loc      = null;
      try {
	loc = new URL(getURL(request), location);
	if (igetHandlePathInfo()) {
	  String pathinfo = (String) request.getState(PATH_INFO);
	  // Given the way pathinfo is computed, it starts with a /
	  loc = new URL(loc, pathinfo.substring(1));
	}
      } catch (Exception ex) {
	ex.printStackTrace();
      }
      reply.setLocation(loc);
      return reply ;
    }
  }
	
}
