📄 versioningfileprovider.java
字号:
/* JSPWiki - a JSP-based WikiWiki clone. Copyright (C) 2001-2002 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.io.*;import java.util.Collection;import java.util.Iterator;import java.util.Properties;import java.util.Date;import java.util.ArrayList;import java.util.List;import org.apache.log4j.Logger;import com.ecyrd.jspwiki.*;/** * Provides a simple directory based repository for Wiki pages. * Pages are held in a directory structure: * <PRE> * Main.txt * Foobar.txt * OLD/ * Main/ * 1.txt * 2.txt * page.properties * Foobar/ * page.properties * </PRE> * * In this case, "Main" has three versions, and "Foobar" just one version. * <P> * The properties file contains the necessary metainformation (such as author) * information of the page. DO NOT MESS WITH IT! * * <P> * All files have ".txt" appended to make life easier for those * who insist on using Windows or other software which makes assumptions * on the files contents based on its name. * * @author Janne Jalkanen */public class VersioningFileProvider extends AbstractFileProvider{ private static final Logger log = Logger.getLogger(VersioningFileProvider.class); public static final String PAGEDIR = "OLD"; public static final String PROPERTYFILE = "page.properties"; public void initialize( WikiEngine engine, Properties properties ) throws NoRequiredPropertyException, IOException { super.initialize( engine, properties ); } /** * Returns the directory where the old versions of the pages * are being kept. */ private File findOldPageDir( String page ) { if( page == null ) { throw new InternalWikiException("Page may NOT be null in the provider!"); } File oldpages = new File( getPageDirectory(), PAGEDIR ); return new File( oldpages, mangleName(page) ); } /** * Goes through the repository and decides which version is * the newest one in that directory. * * @return Latest version number in the repository, or -1, if * there is no page in the repository. */ // FIXME: This is relatively slow. /* private int findLatestVersion( String page ) { File pageDir = findOldPageDir( page ); String[] pages = pageDir.list( new WikiFileFilter() ); if( pages == null ) { return -1; // No such thing found. } int version = -1; for( int i = 0; i < pages.length; i++ ) { int cutpoint = pages[i].indexOf( '.' ); if( cutpoint > 0 ) { String pageNum = pages[i].substring( 0, cutpoint ); try { int res = Integer.parseInt( pageNum ); if( res > version ) { version = res; } } catch( NumberFormatException e ) {} // It's okay to skip these. } } return version; }*/ private int findLatestVersion( String page ) throws ProviderException { int version = -1; try { Properties props = getPageProperties( page ); for( Iterator i = props.keySet().iterator(); i.hasNext(); ) { String key = (String)i.next(); if( key.endsWith(".author") ) { int cutpoint = key.indexOf('.'); if( cutpoint > 0 ) { String pageNum = key.substring(0,cutpoint); try { int res = Integer.parseInt( pageNum ); if( res > version ) { version = res; } } catch( NumberFormatException e ) {} // It's okay to skip these. } } } } catch( IOException e ) { log.error("Unable to figure out latest version - dying...",e); } return version; } /** * Reads page properties from the file system. */ private Properties getPageProperties( String page ) throws IOException { Properties props = new Properties(); File propertyFile = new File( findOldPageDir(page), PROPERTYFILE ); if( propertyFile != null && propertyFile.exists() ) { InputStream in = new FileInputStream( propertyFile ); props.load(in); in.close(); } return props; } /** * Writes the page properties back to the file system. * Note that it WILL overwrite any previous properties. */ private void putPageProperties( String page, Properties properties ) throws IOException { File propertyFile = new File( findOldPageDir(page), PROPERTYFILE ); OutputStream out = new FileOutputStream( propertyFile ); properties.store( out, " JSPWiki page properties for "+page+". DO NOT MODIFY!" ); out.close(); } /** * Figures out the real version number of the page and also checks * for its existence. * * @throws NoSuchVersionException if there is no such version. */ private int realVersion( String page, int requestedVersion ) throws NoSuchVersionException, ProviderException { // // Quickly check for the most common case. // if( requestedVersion == WikiProvider.LATEST_VERSION ) { return -1; } int latest = findLatestVersion(page); if( requestedVersion == latest || (requestedVersion == 1 && latest == -1 ) ) { return -1; } else if( requestedVersion <= 0 || requestedVersion > latest ) { throw new NoSuchVersionException("Requested version "+requestedVersion+", but latest is "+latest ); } return requestedVersion; } public synchronized String getPageText( String page, int version ) throws ProviderException { File dir = findOldPageDir( page ); version = realVersion( page, version ); if( version == -1 ) { // We can let the FileSystemProvider take care // of these requests. return super.getPageText( page, WikiPageProvider.LATEST_VERSION ); } File pageFile = new File( dir, ""+version+FILE_EXT ); if( !pageFile.exists() ) throw new NoSuchVersionException("Version "+version+"does not exist."); return readFile( pageFile ); } // FIXME: Should this really be here? private String readFile( File pagedata ) throws ProviderException { String result = null; InputStream in = null; if( pagedata.exists() ) { if( pagedata.canRead() ) { try { in = new FileInputStream( pagedata ); result = FileUtil.readContents( in, m_encoding ); } catch( IOException e ) { log.error("Failed to read", e); throw new ProviderException("I/O error: "+e.getMessage()); } finally { try { if( in != null ) in.close(); } catch( Exception e ) { log.fatal("Closing failed",e); } } } else { log.warn("Failed to read page from '"+pagedata.getAbsolutePath()+"', possibly a permissions problem"); throw new ProviderException("I cannot read the requested page."); } } else { // This is okay. // FIXME: is it? log.info("New page"); } return result; } // FIXME: This method has no rollback whatsoever. /* This is how the page directory should look like:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -