All Downloads are FREE. Search and download functionalities are using the official Maven repository.

openwfe.org.xml.XmlDocumentCache Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2006, John Mettraux, OpenWFE.org
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 * . Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.  
 * 
 * . Redistributions in binary form must reproduce the above copyright notice, 
 *   this list of conditions and the following disclaimer in the documentation 
 *   and/or other materials provided with the distribution.
 * 
 * . Neither the name of the "OpenWFE" nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: AbstractService.java 2673 2006-05-26 21:08:46Z jmettraux $
 */

//
// XmlDocumentCache.java
//
// [email protected]
//
// generated with 
// jtmpl 1.1.01 2004/05/19 ([email protected])
//

package openwfe.org.xml;

import openwfe.org.Utils;
import openwfe.org.FileUtils;
import openwfe.org.misc.Cache;


/**
 * Caching XML documents (especially if they haven't been modified
 * recently).
 * The main motivation behind this implementation is a serie of
 * benchmarks by Nicolas Modryzk.
 *
 * 

CVS Info : *
$Author$ *
$Id$
* * @author [email protected] */ public class XmlDocumentCache { private final static org.apache.log4j.Logger log = org.apache.log4j.Logger .getLogger(XmlDocumentCache.class.getName()); // // CONSTANTS & co /** * This System Property (SP) 'openwfe.org.xml.XmlDocumentCache' may * take the values 'true', 'false', 'on', 'off'; * When turned off or set to false, it means that no XML caching * will take place. */ public final static String SP_XML_DOCUMENT_CACHE = XmlDocumentCache.class.getName(); // // FIELDS private Cache cache = null; // // CONSTRUCTORS /** * Prepares a cache */ public XmlDocumentCache () { this(77); } /** * Prepares a cache (with a given max number of cached elements). */ public XmlDocumentCache (final int maxSize) { super(); // is caching turned off ? if ( ! Utils.toBoolean (System.getProperty(SP_XML_DOCUMENT_CACHE), true)) { log.info("() XML caching is disabled."); return; } this.cache = new Cache(maxSize); } // // METHODS /** * Returns the XML org.jdom.Element corresponding to the given url * (or the XML contained in the string). * Will attempt to fetch it from the cache, if what's in the cache * is not fresh, will reload the doc and cache it (again). * If it's not present in the cache, will load it and cache it. */ public org.jdom.Document get (final String urlOrXmlString, final boolean shouldValidate) throws org.jdom.JDOMException, java.io.IOException { //if (url.startsWith(XmlUtils.RESOURCE_URL_PREFIX)) // return XmlUtils.extractXml(url, shouldValidate); if (log.isDebugEnabled()) log.debug("get() for |"+urlOrXmlString.substring(0, 10)+"|"); if ( ! urlOrXmlString.trim().startsWith("<")) return get(new java.net.URL(urlOrXmlString), shouldValidate); final String key = "s__" + urlOrXmlString.hashCode() + "__" + urlOrXmlString.length(); //final DocumentEntry de = (DocumentEntry)this.cache.get(key); final DocumentEntry de = getFromCache(key); //log.debug("get() xml is\n"+urlOrXmlString); if (de != null) { if (log.isDebugEnabled()) log.debug("get() doc '"+key+"' already in cache"); return de.cloneDoc(); } final long start = System.currentTimeMillis(); final org.jdom.Document doc = XmlUtils.doExtractXmlDocument (urlOrXmlString, shouldValidate); //this.cache.put // (key, // new DocumentEntry(key, -1, doc)); putInCache(key, -1, doc); if (log.isDebugEnabled()) { log.debug ("get() "+ "had to parse doc '"+key+ "' (took "+(System.currentTimeMillis()-start)+" ms)"); } return doc; } /** * Like get(s, sv) but directly returns the root element. */ public org.jdom.Element getElement (final String urlOrXmlString, final boolean shouldValidate) throws org.jdom.JDOMException, java.io.IOException { final org.jdom.Document doc = get(urlOrXmlString, shouldValidate); if (doc == null) return null; return doc.getRootElement(); // // should we detach() ? } /** * Returns the XML org.jdom.Element corresponding to the given url. * Will attempt to fetch it from the cache, if what's in the cache * is not fresh, will reload the doc and cache it (again). * If it's not present in the cache, will load it and cache it. */ public org.jdom.Document get (final java.net.URL url, final boolean shouldValidate) throws org.jdom.JDOMException, java.io.IOException { final String sUrl = url.toString(); if (log.isDebugEnabled()) log.debug("get() cs"+this.cacheSize()+" for "+sUrl); //final DocumentEntry de = (DocumentEntry)this.cache.get(sUrl); final DocumentEntry de = getFromCache(sUrl); long newLastModified = -1; if (de != null) { newLastModified = FileUtils.getLastModified(url); if (log.isDebugEnabled()) { //log.debug("get() cached "+de.getLastModified()); //log.debug("get() server "+newLastModified); if (newLastModified == 0) log.debug("get() last-modified is 0, have to reload"); } if (newLastModified != 0 && newLastModified <= de.getLastModified()) { return de.cloneDoc(); } // a '0' reply means the server doesn't know when the // ressource was modified. Possibly some CGI / JSP } // // have to reload long start = System.currentTimeMillis(); if (newLastModified < 0) newLastModified = FileUtils.getLastModified(url); //final org.jdom.Element doc = XmlUtils.extractXml(url, shouldValidate); final org.jdom.input.SAXBuilder builder = XmlUtils.getSAXBuilder(shouldValidate); final org.jdom.Document doc = builder.build(url); if (doc == null) return null; //this.cache.put // (sUrl, // new DocumentEntry(sUrl, newLastModified, doc)); putInCache(sUrl, newLastModified, doc); if (log.isDebugEnabled()) { final long duration = System.currentTimeMillis() - start; log.debug ("get() cs"+cacheSize()+ " loading the doc at "+sUrl+" took "+duration+" ms"); } return doc; // note : the Cache class is synchronized } /** * Like get(url, sv) but directly returns the root element. */ public org.jdom.Element getElement (final java.net.URL url, final boolean shouldValidate) throws org.jdom.JDOMException, java.io.IOException { final org.jdom.Document doc = get(url, shouldValidate); if (doc == null) return null; return doc.getRootElement(); // // should we detach() ? } /** * Puts the document and its info into the cache. * If caching is disabled, nothing will get done. */ protected void putInCache (final String key, final long lastModified, final org.jdom.Document doc) { if (this.cache == null) return; this.cache.put (key, new DocumentEntry(key, lastModified, doc)); } /** * Raw get from the cache. * If caching is disabled, will immediately return null. */ protected DocumentEntry getFromCache (final String key) { if (this.cache == null) return null; return (DocumentEntry)this.cache.get(key); } /** * Returns the current size of the cache or null if the caching * of XML documents is disabled. */ protected int cacheSize () { if (this.cache == null) return -1; return this.cache.size(); } // // STATIC METHODS // // INNER CLASSES private class DocumentEntry { private String key = null; private long lastModified = -1; private org.jdom.Document doc = null; public DocumentEntry (final String key, final long lastModified, final org.jdom.Document doc) { super(); this.key = key; this.lastModified = lastModified; this.doc = (org.jdom.Document)doc.clone(); } public long getLastModified () { return this.lastModified; } public org.jdom.Document cloneDoc () { final long start = System.currentTimeMillis(); final org.jdom.Document result = (org.jdom.Document)this.doc.clone(); if (log.isDebugEnabled()) { final long duration = System.currentTimeMillis() - start; log.debug ("cloneDoc() (cs"+XmlDocumentCache.this.cacheSize()+ ") took "+duration+" ms for "+this.key); } // remove me as soon as problem fixed !!! // //if (result == null) // log.warn("cloneDoc() null result !!!"); //else if (result.getRootElement() == null) // log.warn("cloneDoc() null root element !!!"); return result; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy