// ResourceFilter.java
// $Id: ResourceFilter.java,v 1.15 1997/03/28 16:15:19 abaird Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.jigsaw.resources ;

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

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

public class ResourceFilter extends ResourceFrame implements HTTPFilter {
    /**
     * Attribute index - Our target attribute.
     */
    protected static int ATTR_TARGET = -1 ;

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

	try {
	    cls = Class.forName("w3c.jigsaw.resources.ResourceFilter") ;
	} catch (Exception ex) {
	    ex.printStackTrace() ;
	    System.exit(1) ;
	}
	// The class for files having this extension.
	a = new ObjectAttribute("target"
				, "w3c.jigsaw.resources.FilteredResource"
				, null
				, Attribute.DONTSAVE) ;
	ATTR_TARGET = AttributeRegistry.registerAttribute(cls, a) ;
    }

    /**
     * Get this resource's help url.
     * @return An URL, encoded as a String, or <strong>null</strong> if not
     * available.
     */

    public String getHelpURL() {
	httpd server = ((FilteredResource) getTargetResource()).getServer();
	if ( server == null ) 
	    return null;
	String docurl = server.getDocumentationURL();
	if ( docurl == null )
	    return null;
	return docurl + "/" + getClass().getName() + ".html";
    }

    /**
     * Get the help URL for that resource's attribute.
     * @param topic The topic (can be an attribute name, or a property, etc).
     * @return A String encoded URL, or <strong>null</strong>.
     */

    public String getHelpURL(String topic) {
	httpd server = ((FilteredResource) getTargetResource()).getServer();
	if ( server == null ) 
	    return null;
	String docurl = server.getDocumentationURL();
	if ( docurl == null )
	    return null;
	Class defines = AttributeRegistry.getAttributeClass(getClass(), topic);
	if ( defines != null ) 
	    return docurl + "/" + defines.getName() + ".html";
	return null;
    }

    /**
     * Get our target resource.
     */

    public Resource getTargetResource() {
	return (Resource) getValue(ATTR_TARGET, null) ;
    }

    /**
     * Mark this filter as modified.
     * Delegate the dirty bit to our target.
     */

    public void markModified() {
	getTargetResource().markModified() ;
    }

    /**
     * Lookup time filtering.
     * This method is called while Jigsaw performs resource lookup. Each time
     * a lookup end up on the target resource of that filter, this method
     * will be called.
     * @param ls The current lookup state.
     * @param lr The current lookup result.
     * @return A boolean, <strong>true</strong> if this filter has performed
     * the whole lookup, and side-effect the lookup result appropriatelly,
     * <strong>false</strong> otherwise.
     */

    public boolean lookup(LookupState ls, LookupResult lr) 
	throws HTTPException
    {
	return false;
    }

    /**
     * Simplified ingoingFilter API.
     * This is a default, simplified API to the ingoing filter method.
     * @param request The request to filter.
     * @return A Reply instance, or <strong>null</strong> if processing
     * should continue normally.
     * @exception HTTPException If processing should be interrupted, because
     * an abnormal situation occured.
     */

    public Reply ingoingFilter(Request request) 
	throws HTTPException
    {
	return null;
    }

    /**
     * The ingoingFilter method.
     * This is the method that really gets called by Jigsaw core. By default
     * it will invoke the simpler <code>ingoingFilter</code> method,
     * taking only the request has a parameter.
     * @param request The request that is about to be handled.
     * @param filters The whole filter list to be applied to the resource.
     * @param i A pointer into the above array, indicating which filters
     * have already been triggered (the one whose index are lower than 
     * <strong>i</strong>), and what filters have to be triggered (the one
     * whose index are greater or equal to <strong>i+1</strong>).
     * @return A Reply instance, if the filter did know how to answer
     * the request without further processing, <strong>null</strong>
     * otherwise.
     */

    public Reply ingoingFilter(Request request, HTTPFilter filters[], int i)
	throws HTTPException
    {
	return ingoingFilter(request);
    }


    /**
     * Simplified API to the outgoing filter metho.
     * This is a simplified API to the ougoing filter method, you can either
     * overide this method, or the more powerfull one.
     * @param request The original request.
     * @param reply It's original reply.
     * @return A Reply instance, or <strong>null</strong> if processing
     * should continue normally.
     * @exception HTTPException If processing should be interrupted, because
     * an abnormal situation occured.
     */
     
     public Reply outgoingFilter(Request request, Reply reply) 
	 throws HTTPException
    {
	return null;
    }

    public Reply exceptionFilter(Request request
				 , HTTPException ex
				 , HTTPFilter filters[]
				 , int i) {
	return null;
    }

    /**
     * The outgoingFilter method.
     * This method is the one that gets called by Jigsaw core. By default it
     * will call the simpler <code>outgoingFilter</code> method that takes
     * only the request and the reply as parameters.
     * @param request The request that has been processed.
     * @param reply The original reply as emitted by the resource.
     * @param filters The whole filter that applies to the resource.
     * @param i The current index of filters. The <em>i</em> filter is ourself,
     * filters with lower indexes have already been applied, and filters with
     * greater indexes are still to be applied.
     * @return A Reply instance, if that filter know how to complete the
     * request processing, or <strong>null</strong> if reminaing filters
     * are to be called by Jigsaw engine.
     */

    public Reply outgoingFilter(Request request, Reply reply
				, HTTPFilter filters[], int fidx) 
	throws HTTPException
    {
	Reply fr = outgoingFilter(request, reply);
	return (fr != reply) ? fr : null;
    }

    public OutputStream outputFilter(Request request
				     , Reply reply
				     , OutputStream output) {
	return output;
    }

    /**
     * Initialize the filter.
     * @param values The default attribute values.
     */

    public void initialize(Object values[]) {
	// Super initialize:
	super.initialize(values) ;
	// Check our target attributes:
	FilteredResource target = (FilteredResource) getTargetResource() ;
	if ( target == null )
	    throw new HolderInitException("No target !") ;
    }

}
