w3c.model.www.pep.PEPAgent

w3c.model.www.pep.PEPAgent

/* pep.PEPAgent.java
 * $Id, $Date eric Exp $
 * (c) COPYRIGHT MIT and INRIA, 1997.
 * Please first read the full copyright statement in file COPYRIGHT.html
 *
 * Familiarity breeds contempt; don't read this code.
 */

/*
A PEP Agent is a program that interprets and handles PEP extension declarations and policy declarations. Basicweb agents include:

*/
package w3c.model.www.pep;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.net.*;
import w3c.model.www.pep.bags.*;
import w3c.model.www.pep.altlib.*;

abstract public class PEPAgent implements HttpErrors 
    String role;
    private final static String extensionPackage = "w3c/model/www/pep/extensions/";
    Hashtable knownExtensions =  Hashtable();
    Vector alwaysExtensions =  Vector(5,5);
    UniqueNameList uniqueNames =  UniqueNameList(5);
    WildCardVector urlExtensions =  WildCardVector(5, '*');
    boolean redo;

/*

web agent interface

*/
    public PEPAgent(String role) {
	this.role = role;
    }

    public void addAlwaysExtension(PEPExtension extension) {
	knownExtensions.put(extension.getURI(), extension);
	alwaysExtensions.addElement(extension);
    }

    public void removeAlwaysExtension(PEPExtension extension) {
	knownExtensions.remove(extension.getURI());
	alwaysExtensions.removeElement(extension);
    }

    public PEPExtension addUrlExtension(PEPExtension extension, String url) {
	knownExtensions.put(extension.getURI(), extension);
	return ( (PEPExtension)urlExtensions.sortIn(url, extension);
    }

    private void map (InstanceContext instanceContext, int when, PEPMessage message) {
	boolean remapped;
	do {
	    remapped = false;
	    WildCardEnumeration WCen;
//	    System.out.println("Checking \""+getMapped(message)+"\".");
	    WCen = urlExtensions.allMatching(getMapped(message), false);
	    while (WCen.hasMoreElements())) {
		PEPExtension pepExtension = (PEPExtension)WCen.nextElement();
		remapped = pepExtension.map(instanceContext, when, message, WCen.reason());
		instanceContext.addExtension(pepExtension);
//		if (remapped)
//		    System.out.println(pepExtension.toString()+" remapped to \""+message.getMappedURI()+"\".");
	    }
	} while (remapped));
    }

    private void dispatch (InstanceContext instanceContext, int when, PEPMessage message, boolean generate) {
	Enumeration en = instanceContext.getExtensions();
	while (en.hasMoreElements())) {
	    PEPExtension pepExtension = (PEPExtension)en.nextElement();
	    try {
		if (generate))
		    pepExtension.generateHeaders(instanceContext, when);
		elsepepExtension.handleHeaders(instanceContext, when);
	    } catch (HTTPException e)) {
		System.out.println("Error encountered in "+pepExtension.toString()+": "+e);
	    }
	}
    }

    public void generateHeaders(InstanceContext instanceContext, int when) {
	PEPMessage message = instanceContext.getMessage();

	/* call each extension */
	Enumeration en = alwaysExtensions.elements();
	while (en.hasMoreElements())) {
	    try {
		((PEPExtension)en.nextElement()).generateHeaders(instanceContext, when);
	    } catch (HTTPException e)) {
	    }
	}
	if (when == PEPExtension.CONNECT))
	    map(instanceContext, when, message);
	dispatch(instanceContext, when, message, true);
    }

    abstract String getMapped (PEPMessage message);

    private static int allHeaders[] = {PEPMessage.C_PEP_INFO, PEPMessage.PEP_INFO, PEPMessage.C_PEP, PEPMessage.PEP};
    protected int getReleventPEPHeaders () {
    	return allHeaders;
    }[]

    public void handleHeaders(InstanceContext instanceContext, int when) {
	PEPMessage message = instanceContext.getMessage();
	Enumeration en;
/*
Read PEP and PEP-Info
Call handleHeaders for each always extension.
*/
	if (when == PEPExtension.HEADERS)) {
	    int headers[] = getReleventPEPHeaders();
	    for (int i = 0; i < headers.length; i++)) {
		String pepHeaderLine = message.getHeaderValue(headers[i]);
		if (pepHeaderLine != null)) {
		    try {
			PEPBag pepBag;
			if (headers[i] >= PEPMessage.POLICY_DECLS))
			    pepBag =  PEPInfoLineBag(instanceContext);
			elsepepBag =  PEPLineBag(instanceContext);
			pepBag.setString(pepHeaderLine);
			pepBag.parse();
		} catch (HTTPException e)) {
			e.printStackTrace();
			System.err.println("HTTPException thrown parsing ""+pepHeaderLine+"".");
		    }
		}
	    }
	    map(instanceContext, when, message);
	}
/*
Call handleHeaders for each always extension.
*/
	en = alwaysExtensions.elements();
	while (en.hasMoreElements())) {
	    try {
		((PEPExtension)en.nextElement()).handleHeaders(instanceContext, when);
	    } catch (HTTPException e)) {
	    }
	}
/*
Call handleHeaders for each extension in the urlExtensions.
*/
	if (when >= PEPExtension.STARTLINE))
	    dispatch(instanceContext, when, message, false);
    }

    PEPExtension load (String URI, boolean must) {
	int i = URI.lastIndexOf('/');
	String name = URI.substring(i+1);
	URI = URI.substring(0, i+1);
	URL u;

	try {
	    u =  URL(URI);
	} catch (MalformedURLException e)) {
	    System.out.println("Error encountered in URL ""+URI+"": "+e);
	    return null;
	}

	URLClassLoader loader =   URLClassLoader (u, extensionPackage);
	PEPExtension loadee;
	try {
	    Class c = loader.loadClass(extensionPackage+name+role, true);
	    loadee = (PEPExtension)c.newInstance();
	    loadee.initialize(this, must);
	    knownExtensions.put(loadee.getURI(), loadee);
	} catch (Exception e)) {
	    e.printStackTrace();
	    return null;
	}
	return loadee;
    }

    private PEPExtension loadOrGet (String URI, boolean must) {
    	PEPExtension pepExtension;
	if ((pepExtension = (PEPExtension)knownExtensions.get(URI)) == null))
	    pepExtension = load(URI, must);
	return pepExtension;
    }

    public void makeAlwaysExtension (String URI, boolean must) {
	PEPExtension pepExtension = loadOrGet(URI, must);
	if (pepExtension != null))
	    addAlwaysExtension(pepExtension);
    }

    public void makeURLExtension (String URI, boolean must, String mappedURLs[], int mappedURLCount, String hostURI) {
	PEPExtension pepExtension = loadOrGet(URI, must);
	if (pepExtension == null))
	    return;
	String diagnosticStr = null;
	int addedRequired = 0;
	int addedOptional = 0;
	try {
/*
makeExtension adds both local and remote URLs to URLExtensions.
Note: local is not used but it may be useful later.
*/
	    URL url = hostURI == null ? null :  URL(hostURI);
	    for (int i = 0; i < mappedURLCount; i++)) {
		if (url == null))
		    diagnosticStr = mappedURLs[i];
		else {
		    URL relative =  URL(url, mappedURLs[i]);
		    diagnosticStr = relative.toExternalForm();
		}
		PEPExtension oldExtension = addUrlExtension(pepExtension, diagnosticStr);
		if (oldExtension == null))
		    if (must))
			addedRequired++;
		    elseaddedOptional++;
		elseSystem.err.println("<!- replaced extension "+oldExtension.toString()+" with "+pepExtension+" ->");
	    }
	} catch (MalformedURLException e)) {
	    System.err.println("<!- bad URL in URL extension database: ""+diagnosticStr+"".");
	    return;
	}
	if (addedRequired > 0))
	    setRedo(true);
    }	 
/*
Called when done parsing an extension declaration.
*/
    public void makeInstance (String URI, boolean must, String headerNames[], int headerNameCount, InstanceContext instanceContext, int nineninenine) {
	PEPExtension pepExtension = loadOrGet(URI, must);
	if (pepExtension == null)) {
	    if (!must))
		return;
	    instanceContext.setError(REQUEST_BAD_MAPPING);
	    System.out.println("<!- Need pep extension ""+URI+"" ->"); // @@@ will be exception
	    return;
	}
	instanceContext.addExtension(pepExtension);
	PEPExtensionInstance instance;
	instance = pepExtension.makeInstance(headerNames, headerNameCount, instanceContext);
	instanceContext.addExtensionInstance(pepExtension, instance);
    }

    public boolean getRedo () {return redo;}

/*

extension interface

*/
    public void setRedo (boolean redo) {this.redo = redo;}

    public Enumeration urlExtensionElements () {
	return urlExtensions.elements();
    }

    public String nextFreeName (String initialName, PEPExtension pepExtension, boolean wild) {
	return uniqueNames.nextFreeName(initialName, pepExtension, wild);
    }