FileDocCategorySizeDatePackage
DocumentCache.javaAPI DocJava SE 5 API10095Fri Aug 26 14:55:40 BST 2005com.sun.org.apache.xalan.internal.xsltc.dom

DocumentCache

public final class DocumentCache extends Object implements DOMCache
author
Morten Jorgensen

Fields Summary
private int
_size
private Hashtable
_references
private String[]
_URIs
private int
_count
private int
_current
private SAXParser
_parser
private XMLReader
_reader
private XSLTCDTMManager
_dtmManager
private static final int
REFRESH_INTERVAL
Constructors Summary
public DocumentCache(int size)
DocumentCache constructor

        this(size, null);
        try {
            _dtmManager = (XSLTCDTMManager)XSLTCDTMManager.getDTMManagerClass()
                                                          .newInstance();
        } catch (Exception e) {
            throw new SAXException(e);
        }
    
public DocumentCache(int size, XSLTCDTMManager dtmManager)
DocumentCache constructor

	_dtmManager = dtmManager;
	_count = 0;
	_current = 0;
	_size  = size;
	_references = new Hashtable(_size+2);
	_URIs = new String[_size];

	try {
	    // Create a SAX parser and get the XMLReader object it uses
	    final SAXParserFactory factory = SAXParserFactory.newInstance();
	    try {
		factory.setFeature(Constants.NAMESPACE_FEATURE,true);
	    }
	    catch (Exception e) {
		factory.setNamespaceAware(true);
	    }
	    _parser = factory.newSAXParser();
	    _reader = _parser.getXMLReader();
	}
	catch (ParserConfigurationException e) {
	    BasisLibrary.runTimeError(BasisLibrary.NAMESPACES_SUPPORT_ERR);
	    System.exit(-1);
	}
    
Methods Summary
private final longgetLastModified(java.lang.String uri)
Returns the time-stamp for a document's last update

	try {
	    URL url = new URL(uri);
	    URLConnection connection = url.openConnection();
	    long timestamp = connection.getLastModified();
	    // Check for a "file:" URI (courtesy of Brian Ewins)
	    if (timestamp == 0){ // get 0 for local URI
	        if ("file".equals(url.getProtocol())){
	            File localfile = new File(URLDecoder.decode(url.getFile()));
	            timestamp = localfile.lastModified();
	        }
	    }
	    return(timestamp);
	}
	// Brutal handling of all exceptions
	catch (Exception e) {
	    return(System.currentTimeMillis());
	}
    
public voidgetStatistics(java.io.PrintWriter out)
Outputs the cache statistics

	out.println("<h2>DOM cache statistics</h2><center><table border=\"2\">"+
		    "<tr><td><b>Document URI</b></td>"+
		    "<td><center><b>Build time</b></center></td>"+
		    "<td><center><b>Access count</b></center></td>"+
		    "<td><center><b>Last accessed</b></center></td>"+
		    "<td><center><b>Last modified</b></center></td></tr>");

	for (int i=0; i<_count; i++) {
	    CachedDocument doc = (CachedDocument)_references.get(_URIs[i]);
	    out.print("<tr><td><a href=\""+_URIs[i]+"\">"+
		      "<font size=-1>"+_URIs[i]+"</font></a></td>");
	    out.print("<td><center>"+doc.getLatency()+"ms</center></td>");
	    out.print("<td><center>"+doc.getAccessCount()+"</center></td>");
	    out.print("<td><center>"+(new Date(doc.getLastReferenced()))+
		      "</center></td>");
	    out.print("<td><center>"+(new Date(doc.getLastModified()))+
		      "</center></td>");
	    out.println("</tr>");
	}

	out.println("</table></center>");
    
private synchronized voidinsertDocument(java.lang.String uri, com.sun.org.apache.xalan.internal.xsltc.dom.DocumentCache$CachedDocument doc)

	if (_count < _size) {
	    // Insert out URI in circular buffer
	    _URIs[_count++] = uri;
	    _current = 0;
	}
	else {
	    // Remove oldest URI from reference Hashtable
	    _references.remove(_URIs[_current]);
	    // Insert our URI in circular buffer
	    _URIs[_current] = uri;
	    if (++_current >= _size) _current = 0;
	}
	_references.put(uri, doc);
    
private com.sun.org.apache.xalan.internal.xsltc.dom.DocumentCache$CachedDocumentlookupDocument(java.lang.String uri)

	return((CachedDocument)_references.get(uri));
    
private synchronized voidreplaceDocument(java.lang.String uri, com.sun.org.apache.xalan.internal.xsltc.dom.DocumentCache$CachedDocument doc)

	CachedDocument old = (CachedDocument)_references.get(uri);
	if (doc == null)
	    insertDocument(uri, doc);
	else
	    _references.put(uri, doc);
    
public com.sun.org.apache.xalan.internal.xsltc.DOMretrieveDocument(java.lang.String baseURI, java.lang.String href, com.sun.org.apache.xalan.internal.xsltc.Translet trs)
Returns a document either by finding it in the cache or downloading it and putting it in the cache.

	CachedDocument doc;

    String uri = href;
    if (baseURI != null && !baseURI.equals("")) {
        try {
            uri = SystemIDResolver.getAbsoluteURI(uri, baseURI);
        } catch (TransformerException te) {
            // ignore    
        }
    }
    
	// Try to get the document from the cache first
	if ((doc = lookupDocument(uri)) == null) {
	    doc = new CachedDocument(uri);
	    if (doc == null) return null; // better error handling needed!!!
	    doc.setLastModified(getLastModified(uri));
	    insertDocument(uri, doc);
	}
	// If the document is in the cache we must check if it is still valid
	else {
	    long now = System.currentTimeMillis();
	    long chk = doc.getLastChecked();
	    doc.setLastChecked(now);
	    // Has the modification time for this file been checked lately?
	    if (now > (chk + REFRESH_INTERVAL)) {
		doc.setLastChecked(now);
		long last = getLastModified(uri);
		// Reload document if it has been modified since last download
		if (last > doc.getLastModified()) {
		    doc = new CachedDocument(uri);
		    if (doc == null) return null;
		    doc.setLastModified(getLastModified(uri));
		    replaceDocument(uri, doc);
		}
	    }
	    
	}

	// Get the references to the actual DOM and DTD handler
	final DOM dom = doc.getDocument();

	// The dom reference may be null if the URL pointed to a
	// non-existing document
	if (dom == null) return null;

	doc.incAccessCount(); // For statistics

	final AbstractTranslet translet = (AbstractTranslet)trs;

	// Give the translet an early opportunity to extract any
        // information from the DOM object that it would like.
	translet.prepassDocument(dom);

	return(doc.getDocument());