📄 wikiengine.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;import java.io.*;import java.util.*;import org.apache.log4j.*;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import com.ecyrd.jspwiki.plugin.PluginManager;import com.ecyrd.jspwiki.rss.RSSGenerator;import com.ecyrd.jspwiki.providers.WikiPageProvider;import com.ecyrd.jspwiki.providers.ProviderException;import com.ecyrd.jspwiki.attachment.AttachmentManager;import com.ecyrd.jspwiki.attachment.Attachment;import com.ecyrd.jspwiki.auth.AuthorizationManager;import com.ecyrd.jspwiki.auth.UserManager;import com.ecyrd.jspwiki.auth.UserProfile;import com.ecyrd.jspwiki.filters.FilterException;import com.ecyrd.jspwiki.filters.FilterManager;/** * Provides Wiki services to the JSP page. * * <P> * This is the main interface through which everything should go. * * <P> * Using this class: Always get yourself an instance from JSP page * by using the WikiEngine.getInstance() method. Never create a new * WikiEngine() from scratch, unless you're writing tests. * <p> * There's basically only a single WikiEngine for each web application, and * you should always get it using the WikiEngine.getInstance() method. * * @author Janne Jalkanen */public class WikiEngine{ private static final Category log = Category.getInstance(WikiEngine.class); /** True, if log4j has been configured. */ // FIXME: If you run multiple applications, the first application // to run defines where the log goes. Not what we want. private static boolean c_configured = false; /** Stores properties. */ private Properties m_properties; /** The web.xml parameter that defines where the config file is to be found. * If it is not defined, uses the default as defined by DEFAULT_PROPERTYFILE. * @value jspwiki.propertyfile */ public static final String PARAM_PROPERTYFILE = "jspwiki.propertyfile"; /** Property start for any interwiki reference. */ public static final String PROP_INTERWIKIREF = "jspwiki.interWikiRef."; /** If true, then the user name will be stored with the page data.*/ public static final String PROP_STOREUSERNAME= "jspwiki.storeUserName"; /** Define the used encoding. Currently supported are ISO-8859-1 and UTF-8 */ public static final String PROP_ENCODING = "jspwiki.encoding"; /** The name for the base URL to use in all references. */ public static final String PROP_BASEURL = "jspwiki.baseURL"; /** Property name for the "spaces in titles" -hack. */ public static final String PROP_BEAUTIFYTITLE = "jspwiki.breakTitleWithSpaces"; /** Property name for where the jspwiki work directory should be. If not specified, reverts to ${java.tmpdir}. */ public static final String PROP_WORKDIR = "jspwiki.workDir"; /** The name of the cookie that gets stored to the user browser. */ public static final String PREFS_COOKIE_NAME = "JSPWikiUserProfile"; /** Property name for the "match english plurals" -hack. */ public static final String PROP_MATCHPLURALS = "jspwiki.translatorReader.matchEnglishPlurals"; /** Property name for the template that is used. */ public static final String PROP_TEMPLATEDIR = "jspwiki.templateDir"; /** Property name for the default front page. */ public static final String PROP_FRONTPAGE = "jspwiki.frontPage"; private static final String PROP_SPECIALPAGE = "jspwiki.specialPage."; /** Path to the default property file. * @value /WEB_INF/jspwiki.properties */ public static final String DEFAULT_PROPERTYFILE = "/WEB-INF/jspwiki.properties"; /** * Contains the default properties for JSPWiki. */ private static final String[] DEFAULT_PROPERTIES = { "jspwiki.specialPage.Login", "Login.jsp", "jspwiki.specialPage.UserPreferences", "UserPreferences.jsp", "jspwiki.specialPage.Search", "Search.jsp", "jspwiki.specialPage.FindPage", "FindPage.jsp"}; /** Stores an internal list of engines per each ServletContext */ private static Hashtable c_engines = new Hashtable(); /** Should the user info be saved with the page data as well? */ private boolean m_saveUserInfo = true; /** If true, uses UTF8 encoding for all data */ private boolean m_useUTF8 = true; /** If true, we'll also consider english plurals (+s) a match. */ private boolean m_matchEnglishPlurals = true; /** Stores the base URL. */ private String m_baseURL; /** Store the file path to the basic URL. When we're not running as a servlet, it defaults to the user's current directory. */ private String m_rootPath = System.getProperty("user.dir"); /** Stores references between wikipages. */ private ReferenceManager m_referenceManager = null; /** Stores the Plugin manager */ private PluginManager m_pluginManager; /** Stores the Variable manager */ private VariableManager m_variableManager; /** Stores the Attachment manager */ private AttachmentManager m_attachmentManager = null; /** Stores the Page manager */ private PageManager m_pageManager = null; /** Stores the authorization manager */ private AuthorizationManager m_authorizationManager = null; /** Stores the user manager.*/ private UserManager m_userManager = null; private TemplateManager m_templateManager = null; /** Does all our diffs for us. */ private DifferenceEngine m_differenceEngine; /** Handlers page filters. */ private FilterManager m_filterManager; /** Generates RSS feed when requested. */ private RSSGenerator m_rssGenerator; /** Stores the relative URL to the global RSS feed. */ private String m_rssURL; /** Store the ServletContext that we're in. This may be null if WikiEngine is not running inside a servlet container (i.e. when testing). */ private ServletContext m_servletContext = null; /** If true, all titles will be cleaned. */ private boolean m_beautifyTitle = false; /** Stores the template path. This is relative to "templates". */ private String m_templateDir; /** The default front page name. Defaults to "Main". */ private String m_frontPage; /** The time when this engine was started. */ private Date m_startTime; /** The location where the work directory is. */ private String m_workDir; /** Each engine has their own application id. */ private String m_appid = ""; private boolean m_isConfigured = false; // Flag. /** * Gets a WikiEngine related to this servlet. Since this method * is only called from JSP pages (and JspInit()) to be specific, * we throw a RuntimeException if things don't work. * * @param config The ServletConfig object for this servlet. * * @return A WikiEngine instance. * @throws InternalWikiException in case something fails. This * is a RuntimeException, so be prepared for it. */ // FIXME: It seems that this does not work too well, jspInit() // does not react to RuntimeExceptions, or something... public static synchronized WikiEngine getInstance( ServletConfig config ) throws InternalWikiException { return( getInstance( config, null ) ); } /** * Gets a WikiEngine related to the servlet. Works like getInstance(ServletConfig), * but does not force the Properties object. This method is just an optional way * of initializing a WikiEngine for embedded JSPWiki applications; normally, you * should use getInstance(ServletConfig). * * @param config The ServletConfig of the webapp servlet/JSP calling this method. * @param props A set of properties, or null, if we are to load JSPWiki's default * jspwiki.properties (this is the usual case). */ public static synchronized WikiEngine getInstance( ServletConfig config, Properties props ) throws InternalWikiException{ ServletContext context = config.getServletContext(); String appid = Integer.toString(context.hashCode()); //FIXME: Kludge, use real type. config.getServletContext().log( "Application "+appid+" requests WikiEngine."); WikiEngine engine = (WikiEngine) c_engines.get( appid ); if( engine == null ) { context.log(" Assigning new log to "+appid); try { if( props == null ) props = loadWebAppProps( config.getServletContext() ); engine = new WikiEngine( config.getServletContext(), appid, props ); } catch( Exception e ) { context.log( "ERROR: Failed to create a Wiki engine: "+e.getMessage() ); throw new InternalWikiException( "No wiki engine, check logs." ); } c_engines.put( appid, engine ); } return engine;} /** * Instantiate the WikiEngine using a given set of properties. * Use this constructor for testing purposes only. */ public WikiEngine( Properties properties ) throws WikiException { initialize( properties ); } /** * Loads the webapp properties based on servlet context information. * Returns a Properties object containing the settings, or null if unable * to load it. (The default file is WEB-INF/jspwiki.properties, and can * be overridden by setting PARAM_PROPERTYFILE in the server or webapp * configuration.) */ private static Properties loadWebAppProps( ServletContext context ) { String propertyFile = context.getInitParameter(PARAM_PROPERTYFILE); InputStream propertyStream = null; try { // // Figure out where our properties lie. // if( propertyFile == null ) { context.log("No "+PARAM_PROPERTYFILE+" defined for this context, using default from "+DEFAULT_PROPERTYFILE); // Use the default property file. propertyStream = context.getResourceAsStream(DEFAULT_PROPERTYFILE); } else { context.log("Reading properties from "+propertyFile+" instead of default."); propertyStream = new FileInputStream( new File(propertyFile) ); } if( propertyStream == null ) { throw new WikiException("Property file cannot be found!"+propertyFile); } Properties props = new Properties( TextUtil.createProperties( DEFAULT_PROPERTIES ) ); props.load( propertyStream ); return( props ); } catch( Exception e ) { context.log( Release.APPNAME+": Unable to load and setup properties from jspwiki.properties. "+e.getMessage() ); } finally { try { propertyStream.close(); } catch( IOException e ) { context.log("Unable to close property stream - something must be seriously wrong."); } } return( null ); } /** * Instantiate using this method when you're running as a servlet and * WikiEngine will figure out where to look for the property * file. * Do not use this method - use WikiEngine.getInstance() instead. */ protected WikiEngine( ServletContext context, String appid, Properties props ) throws WikiException { InputStream propertyStream = null; String propertyFile = context.getInitParameter(PARAM_PROPERTYFILE); m_servletContext = context; m_appid = appid; try { // // Note: May be null, if JSPWiki has been deployed in a WAR file. // m_rootPath = context.getRealPath("/"); initialize( props ); log.info("Root path for this Wiki is: '"+m_rootPath+"'"); } catch( Exception e ) { context.log( Release.APPNAME+": Unable to load and setup properties from jspwiki.properties. "+e.getMessage() ); } } /** * Does all the real initialization. */ private void initialize( Properties props ) throws WikiException { m_startTime = new Date(); m_properties = props; // // Initialized log4j. However, make sure that // we don't initialize it multiple times. Also, if // all of the log4j statements have been removed from // the property file, we do not do any property setting // either.q // if( !c_configured ) { if( props.getProperty("log4j.rootCategory") != null ) { PropertyConfigurator.configure( props ); } c_configured = true; } log.info("*******************************************"); log.info("JSPWiki "+Release.VERSTR+" starting. Whee!"); log.debug("Configuring WikiEngine..."); // // Create and find the default working directory. // m_workDir = props.getProperty( PROP_WORKDIR ); if( m_workDir == null ) { m_workDir = System.getProperty("java.io.tmpdir", "."); m_workDir += File.separator+Release.APPNAME+"-"+m_appid; } try { File f = new File( m_workDir ); f.mkdirs(); } catch( Exception e ) { log.fatal("Unable to find or create the working directory: "+m_workDir,e); throw new IllegalArgumentException("Unable to find or create the working dir: "+m_workDir); } log.info("JSPWiki working directory is '"+m_workDir+"'"); m_saveUserInfo = TextUtil.getBooleanProperty( props, PROP_STOREUSERNAME, m_saveUserInfo ); m_useUTF8 = "UTF-8".equals( props.getProperty( PROP_ENCODING, "ISO-8859-1" ) ); m_baseURL = props.getProperty( PROP_BASEURL, "" ); m_beautifyTitle = TextUtil.getBooleanProperty( props, PROP_BEAUTIFYTITLE, m_beautifyTitle ); m_matchEnglishPlurals = TextUtil.getBooleanProperty( props, PROP_MATCHPLURALS, m_matchEnglishPlurals ); m_templateDir = props.getProperty( PROP_TEMPLATEDIR, "default" ); m_frontPage = props.getProperty( PROP_FRONTPAGE, "Main" ); // // Initialize the important modules. Any exception thrown by the // managers means that we will not start up. // try { m_pageManager = new PageManager( this, props ); m_filterManager = new FilterManager( this, props ); m_pluginManager = new PluginManager( props ); m_differenceEngine = new DifferenceEngine( props, getContentEncoding() ); m_attachmentManager = new AttachmentManager( this, props ); m_variableManager = new VariableManager( props ); m_templateManager = new TemplateManager( this, props ); m_userManager = new UserManager( this, props ); m_authorizationManager = new AuthorizationManager( this, props ); initReferenceManager(); } catch( Exception e ) { // RuntimeExceptions may occur here, even if they shouldn't. log.error( "Failed to start managers.", e ); throw new WikiException( "Failed to start managers: "+e.getMessage() ); } // // Initialize the good-to-have-but-not-fatal modules. // try { if( TextUtil.getBooleanProperty( props, RSSGenerator.PROP_GENERATE_RSS, false ) ) { m_rssGenerator = new RSSGenerator( this, props ); } } catch( Exception e ) { log.error( "Unable to start RSS generator - JSPWiki will still work, "+ "but there will be no RSS feed.", e ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -