rcsfileprovider.java
来自「我想下载一个东西」· Java 代码 · 共 381 行
JAVA
381 行
/* 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.io.File;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;import java.util.Properties;import java.util.Collection;import java.util.ArrayList;import java.util.List;import java.util.Date;import java.text.SimpleDateFormat;import java.text.ParseException;import org.apache.log4j.Category;import org.apache.oro.text.*;import org.apache.oro.text.regex.*;import com.ecyrd.jspwiki.*;/** * This class implements a simple RCS file provider. NOTE: You MUST * have the RCS package installed for this to work. They must also * be in your path... * * <P> * The RCS file provider extends from the FileSystemProvider, which * means that it provides the pages in the same way. The only difference * is that it implements the version history commands, and also in each * checkin it writes the page to the RCS repository as well. * * @author Janne Jalkanen */// FIXME: Not all commands read their format from the property file yet.public class RCSFileProvider extends FileSystemProvider{ private String m_checkinCommand = "ci -q -m\"author=%u\" -l -t-none %s"; private String m_checkoutCommand = "co -l %s"; private String m_logCommand = "rlog -zLT -r %s"; private String m_fullLogCommand = "rlog -zLT %s"; private String m_checkoutVersionCommand = "co -p -r1.%v %s"; private static final Category log = Category.getInstance(RCSFileProvider.class); public static final String PROP_CHECKIN = "jspwiki.rcsFileProvider.checkinCommand"; public static final String PROP_CHECKOUT = "jspwiki.rcsFileProvider.checkoutCommand"; public static final String PROP_LOG = "jspwiki.rcsFileProvider.logCommand"; public static final String PROP_FULLLOG = "jspwiki.rcsFileProvider.fullLogCommand"; public static final String PROP_CHECKOUTVERSION = "jspwiki.rcsFileProvider.checkoutVersionCommand"; private static final String PATTERN_DATE = "^date:\\s*(.*\\d);"; private static final String PATTERN_AUTHOR = "^\"?author=([\\w\\.\\s\\+\\.\\%]*)\"?"; private static final String PATTERN_REVISION = "^revision \\d+\\.(\\d+)"; private static final String RCSFMT_DATE = "yyyy-MM-dd HH:mm:ss"; private static final String RCSFMT_DATE_UTC = "yyyy/MM/dd HH:mm:ss"; // Date format parsers, placed here to save on object creation private SimpleDateFormat m_rcsdatefmt = new SimpleDateFormat( RCSFMT_DATE ); private SimpleDateFormat m_rcsdatefmt_utc = new SimpleDateFormat( RCSFMT_DATE_UTC ); public void initialize( Properties props ) throws NoRequiredPropertyException, IOException { log.debug("Initing RCS"); super.initialize( props ); m_checkinCommand = props.getProperty( PROP_CHECKIN, m_checkinCommand ); m_checkoutCommand = props.getProperty( PROP_CHECKOUT, m_checkoutCommand ); m_logCommand = props.getProperty( PROP_LOG, m_logCommand ); m_fullLogCommand = props.getProperty( PROP_FULLLOG, m_fullLogCommand ); m_checkoutVersionCommand = props.getProperty( PROP_CHECKOUTVERSION, m_checkoutVersionCommand ); File rcsdir = new File( getPageDirectory(), "RCS" ); if( !rcsdir.exists() ) rcsdir.mkdirs(); log.debug("checkin="+m_checkinCommand); log.debug("checkout="+m_checkoutCommand); log.debug("log="+m_logCommand); log.debug("fulllog="+m_fullLogCommand); log.debug("checkoutversion="+m_checkoutVersionCommand); } // NB: This is a very slow method. public WikiPage getPageInfo( String page, int version ) throws ProviderException { PatternMatcher matcher = new Perl5Matcher(); PatternCompiler compiler = new Perl5Compiler(); PatternMatcherInput input; WikiPage info = super.getPageInfo( page, version ); try { String cmd = m_fullLogCommand; cmd = TextUtil.replaceString( cmd, "%s", mangleName(page)+FILE_EXT ); Process process = Runtime.getRuntime().exec( cmd, null, new File(getPageDirectory()) ); // FIXME: Should this use encoding as well? BufferedReader stdout = new BufferedReader( new InputStreamReader(process.getInputStream() ) ); String line; Pattern headpattern = compiler.compile( PATTERN_REVISION ); // This complicated pattern is required, since on Linux RCS adds // quotation marks, but on Windows, it does not. Pattern userpattern = compiler.compile( PATTERN_AUTHOR ); Pattern datepattern = compiler.compile( PATTERN_DATE ); boolean found = false; while( (line = stdout.readLine()) != null ) { if( matcher.contains( line, headpattern ) ) { MatchResult result = matcher.getMatch(); int vernum = Integer.parseInt( result.group(1) ); if( vernum == version || version == WikiPageProvider.LATEST_VERSION ) { info.setVersion( vernum ); found = true; } } else if( matcher.contains( line, datepattern ) && found ) { MatchResult result = matcher.getMatch(); Date d = parseDate( result.group(1) ); if( d != null ) { info.setLastModified( d ); } else { log.info("WikiPage "+info.getName()+ " has null modification date for version "+ version); } } else if( matcher.contains( line, userpattern ) && found ) { MatchResult result = matcher.getMatch(); info.setAuthor( TextUtil.urlDecodeUTF8(result.group(1)) ); } else if( found && line.startsWith("----") ) { // End of line sign from RCS break; } } // // Especially with certain versions of RCS on Windows, // process.waitFor() hangs unless you read all of the // standard output. So we make sure it's all emptied. // while( (line = stdout.readLine()) != null ) { } process.waitFor(); } catch( Exception e ) { // This also occurs when 'info' was null. log.warn("Failed to read RCS info",e); } return info; } public String getPageText( String page, int version ) throws ProviderException { String result = null; // Let parent handle latest fetches, since the FileSystemProvider // can do the file reading just as well. if( version == WikiPageProvider.LATEST_VERSION ) return super.getPageText( page, version ); log.debug("Fetching specific version "+version+" of page "+page); try { String cmd = m_checkoutVersionCommand; cmd = TextUtil.replaceString( cmd, "%s", mangleName(page)+FILE_EXT ); cmd = TextUtil.replaceString( cmd, "%v", Integer.toString(version ) ); log.debug("Command = '"+cmd+"'"); Process process = Runtime.getRuntime().exec( cmd, null, new File(getPageDirectory()) ); result = FileUtil.readContents( process.getInputStream(), m_encoding ); process.waitFor(); int exitVal = process.exitValue(); log.debug("Done, returned = "+exitVal); // // If fetching failed, assume that this is because of the user // has just migrated from FileSystemProvider, and check // if he's getting version 1. // if( exitVal != 0 && version == 1 ) { result = super.getPageText( page, version ); } } catch( Exception e ) { log.error("RCS checkout failed",e); } return result; } /** * Puts the page into RCS and makes sure there is a fresh copy in * the directory as well. */ public void putPageText( WikiPage page, String text ) { String pagename = page.getName(); // Writes it in the dir. super.putPageText( page, text ); log.debug( "Checking in text..." ); try { String cmd = m_checkinCommand; String author = page.getAuthor(); if( author == null ) author = "unknown"; cmd = TextUtil.replaceString( cmd, "%s", mangleName(pagename)+FILE_EXT ); cmd = TextUtil.replaceString( cmd, "%u", TextUtil.urlEncodeUTF8(author) ); log.debug("Command = '"+cmd+"'"); Process process = Runtime.getRuntime().exec( cmd, null, new File(getPageDirectory()) ); process.waitFor(); log.debug("Done, returned = "+process.exitValue()); } catch( Exception e ) { log.error("RCS checkin failed",e); } } // FIXME: Put the rcs date formats into properties as well. public List getVersionHistory( String page ) { PatternMatcher matcher = new Perl5Matcher(); PatternCompiler compiler = new Perl5Compiler(); PatternMatcherInput input; log.debug("Getting RCS version history"); ArrayList list = new ArrayList(); try { Pattern revpattern = compiler.compile( PATTERN_REVISION ); Pattern datepattern = compiler.compile( PATTERN_DATE ); // This complicated pattern is required, since on Linux RCS adds // quotation marks, but on Windows, it does not. Pattern userpattern = compiler.compile( PATTERN_AUTHOR ); String cmd = TextUtil.replaceString( m_fullLogCommand, "%s", mangleName(page)+FILE_EXT ); Process process = Runtime.getRuntime().exec( cmd, null, new File(getPageDirectory()) ); // FIXME: Should this use encoding as well? BufferedReader stdout = new BufferedReader( new InputStreamReader(process.getInputStream()) ); String line; WikiPage info = null; while( (line = stdout.readLine()) != null ) { if( matcher.contains( line, revpattern ) ) { info = new WikiPage( page ); MatchResult result = matcher.getMatch(); int vernum = Integer.parseInt( result.group(1) ); info.setVersion( vernum ); list.add( info ); } if( matcher.contains( line, datepattern ) ) { MatchResult result = matcher.getMatch(); Date d = parseDate( result.group(1) ); info.setLastModified( d ); } if( matcher.contains( line, userpattern ) ) { MatchResult result = matcher.getMatch(); info.setAuthor( TextUtil.urlDecodeUTF8(result.group(1)) ); } } process.waitFor(); } catch( Exception e ) { log.error( "RCS log failed", e ); } return list; } /** * util method to parse a date string in Local and UTC formats */ private Date parseDate( String str ) { Date d = null; try { d = m_rcsdatefmt.parse( str ); return d; } catch ( ParseException pe ) { } try { d = m_rcsdatefmt_utc.parse( str ); return d; } catch ( ParseException pe ) { } return d; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?