cachingprovider.java

来自「我想下载一个东西」· Java 代码 · 共 555 行 · 第 1/2 页

JAVA
555
字号
/*     JSPWiki - a JSP-based WikiWiki clone.    Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU Lesser General Public License as published by    the Free Software Foundation; either version 2.1 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package com.ecyrd.jspwiki.providers;import java.util.Properties;import java.util.Collection;import java.util.HashMap;import java.util.TreeSet;import java.util.Date;import java.util.ArrayList;import java.util.List;import java.util.Iterator;import java.io.IOException;import org.apache.log4j.Category;import com.ecyrd.jspwiki.*;import com.opensymphony.module.oscache.base.Cache;import com.opensymphony.module.oscache.base.NeedsRefreshException;/** *  Heavily based on ideas by Chris Brooking. * *  @author Janne Jalkanen *  @since 1.6.4 */// FIXME: Keeps a list of all WikiPages in memory - should cache them too.public class CachingProvider    implements WikiPageProvider{    private static final Category   log = Category.getInstance(CachingProvider.class);    private WikiPageProvider m_provider;    private HashMap          m_cache = new HashMap();    private Cache            m_textCache;    private long m_cacheMisses = 0;    private long m_cacheHits   = 0;    private int  m_milliSecondsBetweenChecks = 30000;    /**     *  Defines, in seconds, the amount of time a text will live in the cache     *  at most before requiring a refresh.     */        // FIXME: This can be long, since we check it on our own.    private int  m_refreshPeriod = 24*60*60; // Default is one day.    public static final String PROP_CACHECHECKINTERVAL = "jspwiki.cachingProvider.cacheCheckInterval";    public static final String PROP_CACHECAPACITY      = "jspwiki.cachingProvider.capacity";    private static final int   DEFAULT_CACHECAPACITY   = 200; // Good for a small wiki    public void initialize( Properties properties )        throws NoRequiredPropertyException,               IOException    {        log.debug("Initing CachingProvider");        m_milliSecondsBetweenChecks = TextUtil.parseIntParameter( properties.getProperty(PROP_CACHECHECKINTERVAL),                                                                  m_milliSecondsBetweenChecks );        log.debug("Cache consistency checks every "+m_milliSecondsBetweenChecks+" ms");        //        //  Text cache capacity        //        int capacity = TextUtil.parseIntParameter( properties.getProperty(PROP_CACHECAPACITY),                                                   DEFAULT_CACHECAPACITY );        log.debug("Cache capacity "+capacity+" pages.");        m_textCache = new Cache( true, false,                                 "com.opensymphony.module.oscache.base.algorithm.LRUCache",                                 capacity );        String classname = WikiEngine.getRequiredProperty( properties,                                                            PageManager.PROP_PAGEPROVIDER );                try        {                        Class providerclass = WikiEngine.findWikiClass( classname, "com.ecyrd.jspwiki.providers" );            m_provider = (WikiPageProvider)providerclass.newInstance();            log.debug("Initializing real provider class "+m_provider);            m_provider.initialize( properties );        }        catch( ClassNotFoundException e )        {            log.error("Unable to locate provider class "+classname,e);            throw new IllegalArgumentException("no provider class");        }        catch( InstantiationException e )        {            log.error("Unable to create provider class "+classname,e);            throw new IllegalArgumentException("faulty provider class");        }        catch( IllegalAccessException e )        {            log.error("Illegal access to provider class "+classname,e);            throw new IllegalArgumentException("illegal provider class");        }    }    public boolean pageExists( String page )    {        CacheItem item = (CacheItem)m_cache.get( page );        //        //  A null item means that the page either does not        //  exist, or has not yet been cached; a non-null        //  means that the page does exist.        //        if( item != null )        {            return true;        }        //        //  If we have a list of all pages in memory, then any page        //  not in the cache must be non-existent.        //        //  FIXME: There's a problem here; if someone modifies the        //         repository by adding a page outside JSPWiki,         //         we won't notice it.        if( m_gotall )        {            return false;        }        //        //  We could add the page to the cache here as well,        //  but in order to understand whether that is a        //  good thing or not we would need to analyze        //  the JSPWiki calling patterns extensively.  Presumably        //  it would be a good thing if pageExists() is called        //  many times before the first getPageText() is called,        //  and the whole page is cached.        //        return m_provider.pageExists( page );    }    public String getPageText( String page, int version )        throws ProviderException    {        String result;        if( version == WikiPageProvider.LATEST_VERSION )        {            result = getTextFromCache( page );        }        else        {            CacheItem item = (CacheItem)m_cache.get( page );            //            //  Or is this the latest version fetched by version number?            //            if( item != null && item.m_page.getVersion() == version )            {                result = getTextFromCache( page );            }            else            {                result = m_provider.getPageText( page, version );            }        }        return result;    }    /**     *  Returns true, if the page has been changed outside of JSPWiki.     */    private boolean checkIfPageChanged( CacheItem item )    {        if( item == null ) return false;        long currentTime = System.currentTimeMillis();        if( currentTime - item.m_lastChecked > m_milliSecondsBetweenChecks )        {            try            {                WikiPage cached  = item.m_page;                WikiPage current = m_provider.getPageInfo( cached.getName(),                                                           LATEST_VERSION );                item.m_lastChecked = currentTime;                long epsilon = 1000L; // FIXME: This should be adjusted according to provider granularity.                Date currentModified = current.getLastModified();                Date cachedModified  = cached.getLastModified();                if( currentModified != null && cachedModified != null &&                     currentModified.getTime() - cachedModified.getTime() > epsilon )                {                                    log.debug("Page "+current.getName()+" has been externally modified, refreshing contents.");                    return true;                }            }            catch( ProviderException e )            {                log.error("While checking cache, got error: ",e);            }        }        return false;    }    /**     *  Removes the page from cache, and attempts to reload all information.     */    private synchronized void revalidatePage( WikiPage page )        throws ProviderException    {        m_cache.remove( page.getName() );        m_textCache.flushEntry( page.getName() );        addPage( page.getName(), null ); // If fetch fails, we want info to go directly to user    }    /**     *  Attempts to fetch text from the cache.     */    private String getTextFromCache( String page )        throws ProviderException    {        CacheItem item = (CacheItem)m_cache.get( page );        //        //  Check if page has been changed externally.  If it has, then        //  we need to refresh all of the information.        //        if( checkIfPageChanged( item ) )        {            revalidatePage( item.m_page );            item = (CacheItem) m_cache.get( page );        }        if( item == null )        {            // Page has never been seen.            // log.debug("Page "+page+" never seen.");            String text = m_provider.getPageText( page, WikiPageProvider.LATEST_VERSION );            addPage( page, text );            m_cacheMisses++;            return text;        }        else        {            String text;            try

⌨️ 快捷键说明

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