📄 pluginmanager.java
字号:
/* 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.plugin;import org.apache.oro.text.regex.*;import org.apache.log4j.Logger;import java.io.StreamTokenizer;import java.io.StringReader;import java.io.StringWriter;import java.io.PrintWriter;import java.io.IOException;import java.util.NoSuchElementException;import java.util.Map;import java.util.Vector;import java.util.Iterator;import java.util.Properties;import java.util.StringTokenizer;import java.util.HashMap;import com.ecyrd.jspwiki.WikiContext;import com.ecyrd.jspwiki.FileUtil;import com.ecyrd.jspwiki.TextUtil;import com.ecyrd.jspwiki.InternalWikiException;import com.ecyrd.jspwiki.util.ClassUtil;/** * Manages plugin classes. There exists a single instance of PluginManager * per each instance of WikiEngine, that is, each JSPWiki instance. * <P> * A plugin is defined to have three parts: * <OL> * <li>The plugin class * <li>The plugin parameters * <li>The plugin body * </ol> * * For example, in the following line of code: * <pre> * [{INSERT com.ecyrd.jspwiki.plugin.FunnyPlugin foo='bar' * blob='goo' * * abcdefghijklmnopqrstuvw * 01234567890}] * </pre> * * The plugin class is "com.ecyrd.jspwiki.plugin.FunnyPlugin", the * parameters are "foo" and "blob" (having values "bar" and "goo", * respectively), and the plugin body is then * "abcdefghijklmnopqrstuvw\n01234567890". The plugin body is * accessible via a special parameter called "_body". * <p> * If the parameter "debug" is set to "true" for the plugin, * JSPWiki will output debugging information directly to the page if there * is an exception. * <P> * The class name can be shortened, and marked without the package. * For example, "FunnyPlugin" would be expanded to * "com.ecyrd.jspwiki.plugin.FunnyPlugin" automatically. It is also * possible to defined other packages, by setting the * "jspwiki.plugin.searchPath" property. See the included * jspwiki.properties file for examples. * <P> * Even though the nominal way of writing the plugin is * <pre> * [{INSERT pluginclass WHERE param1=value1...}], * </pre> * it is possible to shorten this quite a lot, by skipping the * INSERT, and WHERE words, and dropping the package name. For * example: * * <pre> * [{INSERT com.ecyrd.jspwiki.plugin.Counter WHERE name='foo'}] * </pre> * * is the same as * <pre> * [{Counter name='foo'}] * </pre> * * @author Janne Jalkanen * @since 1.6.1 */public class PluginManager{ private static Logger log = Logger.getLogger( PluginManager.class ); /** * This is the default package to try in case the instantiation * fails. */ public static final String DEFAULT_PACKAGE = "com.ecyrd.jspwiki.plugin"; /** * The property name defining which packages will be searched for properties. */ public static final String PROP_SEARCHPATH = "jspwiki.plugin.searchPath"; /** * The name of the body content. Current value is "_body". */ public static final String PARAM_BODY = "_body"; /** * A special name to be used in case you want to see debug output */ public static final String PARAM_DEBUG = "debug"; Vector m_searchPath = new Vector(); Pattern m_pluginPattern; private boolean m_pluginsEnabled = true; /** * Create a new PluginManager. * * @param props Contents of a "jspwiki.properties" file. */ public PluginManager( Properties props ) { String packageNames = props.getProperty( PROP_SEARCHPATH ); if( packageNames != null ) { StringTokenizer tok = new StringTokenizer( packageNames, "," ); while( tok.hasMoreTokens() ) { m_searchPath.add( tok.nextToken() ); } } // // The default package is always added. // m_searchPath.add( DEFAULT_PACKAGE ); PatternCompiler compiler = new Perl5Compiler(); try { m_pluginPattern = compiler.compile( "\\{?(INSERT)?\\s*([\\w\\._]+)[ \\t]*(WHERE)?[ \\t]*" ); } catch( MalformedPatternException e ) { log.fatal("Internal error: someone messed with pluginmanager patterns.", e ); throw new InternalWikiException( "PluginManager patterns are broken" ); } } /** * Enables or disables plugin execution. */ public void enablePlugins( boolean enabled ) { m_pluginsEnabled = enabled; } /** * Returns plugin execution status. If false, plugins are not * executed when they are encountered on a WikiPage, and an * empty string is returned in their place. */ public boolean pluginsEnabled() { return( m_pluginsEnabled ); } /** * Returns true if the link is really command to insert * a plugin. * <P> * Currently we just check if the link starts with "{INSERT", * or just plain "{" but not "{$". * * @param link Link text, i.e. the contents of text between []. * @return True, if this link seems to be a command to insert a plugin here. */ public static boolean isPluginLink( String link ) { return link.startsWith("{INSERT") || (link.startsWith("{") && !link.startsWith("{$")); } /** * Attempts to locate a plugin class from the class path * set in the property file. * * @param classname Either a fully fledged class name, or just * the name of the file (that is, * "com.ecyrd.jspwiki.plugin.Counter" or just plain "Counter"). * * @return A found class. * * @throws ClassNotFoundException if no such class exists. */ private Class findPluginClass( String classname ) throws ClassNotFoundException { return ClassUtil.findClass( m_searchPath, classname ); } /** * Outputs a HTML-formatted version of a stack trace. */ private String stackTrace( Map params, Throwable t ) { StringWriter sw = new StringWriter(); PrintWriter out = new PrintWriter( sw ); out.println("<div class=\"debug\">"); out.println("Plugin execution failed, stack trace follows:"); out.println("<pre>"); t.printStackTrace( out ); out.println("</pre>"); out.println("<b>Parameters to the plugin</b>"); out.println("<ul>"); for( Iterator i = params.keySet().iterator(); i.hasNext(); ) { String key = (String) i.next(); out.println(" <li>'"+key+"'='"+params.get(key)+"'</li>"); } out.println("</ul>"); out.println("</div>"); out.flush(); return sw.toString(); } /** * Executes a plugin class in the given context. * <P>Used to be private, but is public since 1.9.21. * * @param context The current WikiContext. * @param classname The name of the class. Can also be a * shortened version without the package name, since the class name is searched from the * package search path. * * @param params A parsed map of key-value pairs. * * @return Whatever the plugin returns. * * @throws PluginException If the plugin execution failed for * some reason. * * @since 2.0 */ public String execute( WikiContext context, String classname, Map params )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -