pushcachefilter.java

来自「很棒的web服务器源代码」· Java 代码 · 共 317 行

JAVA
317
字号
// PushCacheFilter.java// $Id: PushCacheFilter.java,v 1.1 2001/10/03 15:00:46 ylafon Exp $// (c) COPYRIGHT MIT, INRIA and Keio, 2001.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.www.protocol.http.cache.push;import java.net.URL;import org.w3c.www.http.HTTP;import org.w3c.www.protocol.http.Reply;import org.w3c.www.protocol.http.Request;import org.w3c.www.protocol.http.HttpException;import org.w3c.www.protocol.http.HttpManager;import org.w3c.www.protocol.http.PropRequestFilterException;import org.w3c.www.protocol.http.cache.CacheFilter;import org.w3c.www.protocol.http.cache.CacheSweeper;import org.w3c.www.protocol.http.cache.CachedResource;import org.w3c.www.protocol.http.cache.EntityCachedResource;import org.w3c.www.protocol.http.cache.InvalidCacheException;import org.w3c.www.protocol.http.cache.CacheState;import org.w3c.www.protocol.http.cache.CacheValidator;import org.w3c.www.protocol.http.cache.CacheSerializer;import org.w3c.www.protocol.http.cache.ActiveStream;/** * PushCacheFilter * Based heavily on (much code stolen from) CacheFilter * The important differences are in the initialization where the  * PushCacheListener is started, and in ingoingFilter where if  * the requested resource is present in the cache and is a PUSH * resource, then the resource is returned immediately without * checking for expiry etc.  This allows us to insert pages from * "virtual" web sites such as http://www.push.data/sensor1.html * * @author Paul Henshaw, The Fantastic Corporation, Paul.Henshaw@fantastic.com * @version $Revision: 1.1 $ * $Id: PushCacheFilter.java,v 1.1 2001/10/03 15:00:46 ylafon Exp $ */public class PushCacheFilter extends CacheFilter {    /**     * Property name used to acquire port number for {@link PushCacheListener}     * value is "org.w3c.www.protocol.http.cache.push.portnumber";     */    public static final String PORT_NUM_P = 	"org.w3c.www.protocol.http.cache.push.portnumber";    /**     * Default port number to use if property value is not supplied      * value is 9876     */    public static final int DEFAULT_PORT_NUM=9876;    /**     * Access to PushCacheStore     */    public PushCacheStore getPushCacheStore() {	return((PushCacheStore)super.getStore());    }    /**     * check if we can use the cache or not for this request     * It marks the request as being not cachable if false.     * @param a request, the incoming client-side request     * @return a boolean, true if we can use the cache     */    public boolean canUseCache(Request req) {	return true;    }    /**     * The request pre-processing hook.     * Before each request is launched, all filters will be called back through     * this method. They will generally set up additional request header     * fields to enhance the request.     * @param request The request that is about to be launched.     * @return An instance of Reply if the filter could handle the request,     * or <strong>null</strong> if processing should continue normally.     * @exception HttpException If the filter is supposed to fulfill the     * request, but some error happened during that processing.     */    public Reply ingoingFilter(Request request) throws HttpException {	// can we use the cache?	if (!canUseCache(request)) {	    if (debug) {		trace(request, "*** Can't use cache");	    }	    // we will invalidate this resource, will do that only	    // on real entity resource, not on negotiated ones	    if (connected) {		CachedResource res = null;		EntityCachedResource invalidRes = null;		try {		    String requrl = request.getURL().toExternalForm();		    res = store.getCachedResourceReference(requrl);		    if (res != null) {			invalidRes = (EntityCachedResource)			    res.lookupResource(request);		    }		} catch (InvalidCacheException ex) {		    invalidRes = null;		}		if (invalidRes != null) {		    invalidRes.setWillRevalidate(true);		}		request.setState(STATE_NOCACHE, Boolean.TRUE);		return null;	    } else {		// disconnected, abort now!		Reply reply = request.makeReply(HTTP.GATEWAY_TIMEOUT);		reply.setContent("The cache cannot be use for "				 + "<p><code>"+request.getMethod()+"</code> "				 + "<strong>"+request.getURL()+"</strong>"				 + ". <p>It is disconnected.");		return reply;	    }	}	// let's try to get the resource!	String requrl = request.getURL().toExternalForm();	// in the pre-cache, wait for full download	// FIXME should be better than this behaviour...	// see EntityCachedResource perform's FIXME ;)	if (precache.containsKey(requrl)) {	    if (debug)		System.out.println("*** Already downloading: "+ requrl);	    try {		CachedResource cr = (CachedResource)precache.get(requrl);		return cr.perform(request);	    } catch (Exception ex) {		// there was a problem with the previous request, 		// it may be better to do it by ourself	    }	}		CachedResource res = null;	try {	    res = store.getCachedResourceReference(requrl);	} catch (InvalidCacheException ex) {	    res = null;	}	// Is this a push resource ?	try {	    if(PushCacheManager.instance().isPushResource(res)) {		EntityCachedResource ecr=(EntityCachedResource) 		    res.lookupResource(request);			    		if(ecr!=null) {		    Reply reply = ecr.perform(request);		    return reply;		}	    }	}	catch(Exception e) {		e.printStackTrace();	}	// /PSLH	// are we disconnected?	if (request.checkOnlyIfCached() || !connected ) {	    // and no entries...	    EntityCachedResource ecr = null;	    if (res != null) {		ecr = (EntityCachedResource) res.lookupResource(request);	    }	    if ((res == null) || (ecr == null)) {		if ( debug )		    trace(request, "unavailable (disconnected).");		Reply reply = request.makeReply(HTTP.GATEWAY_TIMEOUT);		reply.setContent("The cache doesn't have an entry for "				 + "<p><strong>"+request.getURL()+"</strong>"				 + ". <p>And it is disconnected.");		return reply;	    }	    // yeah!	    if (debug) {		trace(request, (connected) ? " hit - only if cached" : 		      " hit while disconneced" );	    }	    if (!validator.isValid(ecr, request)) {		addWarning(request, WARN_STALE);	    }	    addWarning(request, WARN_DISCONNECTED);	    Reply reply = ecr.perform(request);		// Add any warnings collected during processing to the reply:	    setWarnings(request, reply);//FIXME	    request.setState(STATE_HOW, HOW_HIT);	    return reply;	}	// in connected mode, we should now take care of revalidation and such	if (res != null) {	    // if not fully loaded, ask for a revalidation FIXME	    if ((res.getLoadState() == CachedResource.STATE_LOAD_PARTIAL) ||		(res.getLoadState() == CachedResource.STATE_LOAD_ERROR)) {		setRequestRevalidation(res, request);		return null;	    }	    if ( validator.isValid(res, request) ) {		try {		    store.updateResourceGeneration(res);		} catch (InvalidCacheException ex) {		    // should be ok so...		}//FIXME	    request.setState(STATE_HOW, HOW_HIT);		Reply rep = res.perform(request);		return rep;	    } else {		if (debug) {		    System.out.println("*** Revalidation asked for " + requrl);		}		// ask for a revalidation		setRequestRevalidation(res, request);		return null;	    }	}	// lock here while we are waiting for the download	while (uritable.containsKey(requrl)) {	    synchronized (uritable) {		try {		    uritable.wait();		} catch (InterruptedException ex) {}	    }	    if (precache.containsKey(requrl)) {		if (debug)		    System.out.println("*** Already downloading: "+ requrl);		CachedResource cr = (CachedResource)precache.get(requrl);		return cr.perform(request);	    }	    uritable.put(requrl, requrl);	}	return null;    }    /**     * Almost identical to CacheFilter.initialize, but creates a     * PushCacheStore instead of a CacheStore and additionaly      * starts the PushCacheListener     */    public void initialize(HttpManager manager) 	throws PropRequestFilterException     {	try {	    String validator_c;	    String sweeper_c;	    String serializer_c;	    props = manager.getProperties();	    shared    = props.getBoolean(SHARED_P, false);	    connected = props.getBoolean(CACHE_CONNECTED_P, true);	    debug     = props.getBoolean(DEBUG_P, false);	    // now create the add-on classes	    validator_c = props.getString(VALIDATOR_P,                "org.w3c.www.protocol.http.cache.SimpleCacheValidator");	    sweeper_c = props.getString(SWEEPER_P,		"org.w3c.www.protocol.http.cache.SimpleCacheSweeper");	    serializer_c = props.getString(SERIALIZER_P,		"org.w3c.www.protocol.http.cache.SimpleCacheSerializer");	    try {		Class c;		c = Class.forName(validator_c);		validator =  (CacheValidator) c.newInstance();		validator.initialize(this);		c = Class.forName(sweeper_c);		sweeper = (CacheSweeper) c.newInstance();		sweeper.initialize(this);		c = Class.forName(serializer_c);		serializer = (CacheSerializer) c.newInstance();	    } catch (Exception ex) {		// a fatal error! The cache won't be loaded...		ex.printStackTrace();		throw new PropRequestFilterException("Unable to start cache");	    }	    // now create the store as we have the basic things here	    store = new PushCacheStore();	    try {		store.initialize(this);	    } catch (InvalidCacheException ex) {		// hum no worky, should do some action there!		if (debug) {		    ex.printStackTrace();		}	    }	    // now start the sweeper	    sweeper.start();	    // Start the ActiveStream handler:	    ActiveStream.initialize();	    // Register for property changes:	    props.registerObserver(this);	    // Now, we are ready, register that filter:	    manager.setFilter(this);	    //	    // Create and start a PushCacheListener	    //	    int portNum=props.getInteger(PORT_NUM_P,DEFAULT_PORT_NUM);	    PushCacheListener listener=new PushCacheListener(portNum);	    listener.start();	    //	    // Register this filter with the PushCacheManager	    //	    PushCacheManager.instance().registerFilter(this);	}	catch(Exception e) {	    e.printStackTrace();	}    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?