You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ja...@apache.org on 2008/11/10 21:50:39 UTC
svn commit: r712830 - in /incubator/jspwiki/trunk: ./ src/com/ecyrd/jspwiki/
src/com/ecyrd/jspwiki/filters/ src/com/ecyrd/jspwiki/modules/
src/com/ecyrd/jspwiki/plugin/ src/com/ecyrd/jspwiki/ui/
src/com/ecyrd/jspwiki/ui/admin/beans/ src/org/apache/jspw...
Author: jalkanen
Date: Mon Nov 10 12:50:38 2008
New Revision: 712830
URL: http://svn.apache.org/viewvc?rev=712830&view=rev
Log:
JSPWIKI-423: Plugins and filters now use annotations instead of
jspwiki_module.xml. Editors still do it the old way, though.
jspwiki_module.xml still is used to optionally locate the packages,
through "<module package="org.mycompany"/>". Please see PluginManager
for documentation.
Modified:
incubator/jspwiki/trunk/ChangeLog
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/FilterManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/ProfanityFilter.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/SpamFilter.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/ModuleManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/WikiModuleInfo.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/IfPlugin.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/Image.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/PluginManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/EditorManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/admin/beans/PluginBean.java
incubator/jspwiki/trunk/src/org/apache/jspwiki/api/ModuleData.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/PluginManagerTest.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/SamplePlugin.java
Modified: incubator/jspwiki/trunk/ChangeLog
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/ChangeLog?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/ChangeLog (original)
+++ incubator/jspwiki/trunk/ChangeLog Mon Nov 10 12:50:38 2008
@@ -1,3 +1,15 @@
+2008-11-10 Janne Jalkanen <ja...@apache.org>
+
+ * 3.0.0-svn-5
+
+ * Stripes-1.5 resides now in lib instead of tests/lib. Yay!
+
+ * JSPWIKI-423: Plugins and filters now use annotations instead of
+ jspwiki_module.xml. Editors still do it the old way, though.
+ jspwiki_module.xml still is used to optionally locate the packages,
+ through "<module package="org.mycompany"/>". Please see PluginManager
+ for documentation.
+
2008-11-10 Harry Metske <me...@apache.org>
* 3.0.0-svn-4
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/Release.java Mon Nov 10 12:50:38 2008
@@ -77,7 +77,7 @@
* <p>
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "4";
+ public static final String BUILD = "5";
/**
* This is the generic version string you should use
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/FilterManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/FilterManager.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/FilterManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/FilterManager.java Mon Nov 10 12:50:38 2008
@@ -27,6 +27,8 @@
import java.net.URL;
import java.util.*;
+import net.sourceforge.stripes.util.ResolverUtil;
+
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
@@ -41,6 +43,8 @@
import com.ecyrd.jspwiki.event.WikiPageEvent;
import com.ecyrd.jspwiki.modules.ModuleManager;
import com.ecyrd.jspwiki.modules.WikiModuleInfo;
+import com.ecyrd.jspwiki.plugin.WikiPlugin;
+import com.ecyrd.jspwiki.plugin.PluginManager.WikiPluginInfo;
import com.ecyrd.jspwiki.util.ClassUtil;
import com.ecyrd.jspwiki.util.PriorityList;
@@ -210,7 +214,7 @@
try
{
- registerFilters();
+ registerAllFilters();
if( m_engine.getServletContext() != null )
{
@@ -466,61 +470,29 @@
return modules;
}
- private void registerFilters()
+ private void registerAllFilters()
{
log.info( "Registering filters" );
- SAXBuilder builder = new SAXBuilder();
-
- try
+ List<String> searchPath = buildPluginSearchPath( m_engine.getWikiProperties() );
+
+ ResolverUtil<PageFilter> resolver = new ResolverUtil<PageFilter>();
+
+ String[] paths = searchPath.toArray( new String[0] );
+ resolver.findImplementations( PageFilter.class, paths );
+
+ Set<Class<? extends PageFilter>> resultSet = resolver.getClasses();
+
+ log.debug( "Found "+resultSet.size()+" pagefilters" );
+
+ for( Class<? extends PageFilter> clazz : resultSet )
{
- //
- // Register all filters which have created a resource containing its properties.
- //
- // Get all resources of all plugins.
- //
-
- Enumeration resources = getClass().getClassLoader().getResources( PLUGIN_RESOURCE_LOCATION );
+ PageFilterInfo pluginInfo = PageFilterInfo.newInstance( clazz );
- while( resources.hasMoreElements() )
+ if( pluginInfo != null )
{
- URL resource = (URL) resources.nextElement();
-
- try
- {
- log.debug( "Processing XML: " + resource );
-
- Document doc = builder.build( resource );
-
- List plugins = XPath.selectNodes( doc, "/modules/filter");
-
- for( Iterator i = plugins.iterator(); i.hasNext(); )
- {
- Element pluginEl = (Element) i.next();
-
- String className = pluginEl.getAttributeValue("class");
-
- PageFilterInfo pluginInfo = PageFilterInfo.newInstance( className, pluginEl );
-
- if( pluginInfo != null )
- {
- registerPlugin( pluginInfo );
- }
- }
- }
- catch( java.io.IOException e )
- {
- log.error( "Couldn't load " + PLUGIN_RESOURCE_LOCATION + " resources: " + resource, e );
- }
- catch( JDOMException e )
- {
- log.error( "Error parsing XML for filter: "+PLUGIN_RESOURCE_LOCATION );
- }
- }
- }
- catch( java.io.IOException e )
- {
- log.error( "Couldn't load all " + PLUGIN_RESOURCE_LOCATION + " resources", e );
+ registerPlugin( pluginInfo );
+ }
}
}
@@ -536,17 +508,16 @@
*/
private static final class PageFilterInfo extends WikiModuleInfo
{
- private PageFilterInfo( String name )
+ private PageFilterInfo( Class<? extends PageFilter> clazz )
{
- super(name);
+ super(clazz.getName());
+ initializeFromClass( clazz );
}
- protected static PageFilterInfo newInstance(String className, Element pluginEl)
+ protected static PageFilterInfo newInstance(Class<? extends PageFilter> clazz)
{
- if( className == null || className.length() == 0 ) return null;
- PageFilterInfo info = new PageFilterInfo( className );
+ PageFilterInfo info = new PageFilterInfo( clazz );
- info.initializeFromXML( pluginEl );
return info;
}
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/ProfanityFilter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/ProfanityFilter.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/ProfanityFilter.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/ProfanityFilter.java Mon Nov 10 12:50:38 2008
@@ -39,6 +39,7 @@
* is case unsensitive.
*
*/
+@Deprecated
public class ProfanityFilter extends BasicPageFilter
{
private static Logger log = Logger.getLogger(ProfanityFilter.class);
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/SpamFilter.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/SpamFilter.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/SpamFilter.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/filters/SpamFilter.java Mon Nov 10 12:50:38 2008
@@ -32,6 +32,7 @@
import org.apache.commons.jrcs.diff.*;
import org.apache.commons.jrcs.diff.myers.MyersDiff;
import org.apache.commons.lang.time.StopWatch;
+import org.apache.jspwiki.api.ModuleData;
import org.apache.log4j.Logger;
import org.apache.oro.text.regex.*;
@@ -70,6 +71,7 @@
*
* @since 2.1.112
*/
+@ModuleData( author = "JSPWiki development group" )
public class SpamFilter
extends BasicPageFilter
{
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/ModuleManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/ModuleManager.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/ModuleManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/ModuleManager.java Mon Nov 10 12:50:38 2008
@@ -20,7 +20,15 @@
*/
package com.ecyrd.jspwiki.modules;
-import java.util.Collection;
+import java.net.URL;
+import java.util.*;
+
+import org.apache.log4j.Logger;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.xpath.XPath;
import com.ecyrd.jspwiki.Release;
import com.ecyrd.jspwiki.WikiEngine;
@@ -32,13 +40,20 @@
{
/**
+ * The property name defining which packages will be searched for modules.
+ */
+ public static final String PROP_SEARCHPATH = "jspwiki.plugin.searchPath";
+
+ /**
* Location of the property-files of plugins.
* (Each plugin should include this property-file in its jar-file)
*/
- public static final String PLUGIN_RESOURCE_LOCATION = "ini/jspwiki_module.xml";
+ public static final String MODULE_RESOURCE_LOCATION = "ini/jspwiki_module.xml";
protected WikiEngine m_engine;
+ private static Logger log = Logger.getLogger( ModuleManager.class );
+
private boolean m_loadIncompatibleModules = false;
/**
@@ -78,4 +93,74 @@
* @return A Collection of WikiModuleInfo instances.
*/
public abstract Collection modules();
+
+ /**
+ * Builds a search path from three components:
+ * <ol>
+ * <li>The default packages.
+ * <li>The contents of {@value #PROP_SEARCHPATH}
+ * <li>Whatever can be located from the contents of the ini-files
+ * </ol>
+ *
+ * @param props
+ * @return A List of package names which should be scanned for modules.
+ */
+ protected List<String> buildPluginSearchPath( Properties props )
+ {
+ ArrayList<String> list = new ArrayList<String>();
+ list.add( "com.ecyrd.jspwiki" );
+ list.add( "org.apache.jspwiki" );
+
+ String packageNames = props.getProperty( PROP_SEARCHPATH );
+
+ if( packageNames != null )
+ {
+ StringTokenizer tok = new StringTokenizer( packageNames, "," );
+
+ while( tok.hasMoreTokens() )
+ {
+ list.add( tok.nextToken().trim() );
+ }
+ }
+
+ SAXBuilder builder = new SAXBuilder();
+
+ try
+ {
+ Enumeration resources = getClass().getClassLoader().getResources( MODULE_RESOURCE_LOCATION );
+
+ while( resources.hasMoreElements() )
+ {
+ URL resource = (URL) resources.nextElement();
+
+ try
+ {
+ Document doc = builder.build( resource );
+
+ List packages = XPath.selectNodes( doc, "/modules/@package");
+
+ for( Iterator i = packages.iterator(); i.hasNext(); )
+ {
+ Attribute a = (Attribute) i.next();
+
+ list.add( a.getValue().trim() );
+ }
+ }
+ catch( java.io.IOException e )
+ {
+ log.error( "Couldn't load " + MODULE_RESOURCE_LOCATION + " resources: " + resource, e );
+ }
+ catch( JDOMException e )
+ {
+ log.error( "Error parsing XML for plugin: "+MODULE_RESOURCE_LOCATION );
+ }
+ }
+ }
+ catch( java.io.IOException e )
+ {
+ log.error( "Couldn't load all " + MODULE_RESOURCE_LOCATION + " resources", e );
+ }
+
+ return list;
+ }
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/WikiModuleInfo.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/WikiModuleInfo.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/WikiModuleInfo.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/modules/WikiModuleInfo.java Mon Nov 10 12:50:38 2008
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.net.URL;
+import org.apache.jspwiki.api.ModuleData;
import org.jdom.Element;
import com.ecyrd.jspwiki.FileUtil;
@@ -39,9 +40,9 @@
implements Comparable<WikiModuleInfo>
{
protected String m_name;
- protected String m_scriptLocation;
+ protected String[] m_scriptLocation;
protected String m_scriptText;
- protected String m_stylesheetLocation;
+ protected String[] m_stylesheetLocation;
protected String m_stylesheetText;
protected String m_author;
protected URL m_resource;
@@ -94,14 +95,29 @@
*/
protected void initializeFromXML( Element el )
{
- m_scriptLocation = el.getChildText("script");
- m_stylesheetLocation = el.getChildText("stylesheet");
+ m_scriptLocation = new String[] { el.getChildText("script") };
+ m_stylesheetLocation = new String[] { el.getChildText("stylesheet") };
m_author = el.getChildText("author");
m_minVersion = el.getChildText("minVersion");
m_maxVersion = el.getChildText("maxVersion");
m_adminBeanClass = el.getChildText("adminBean");
}
+ protected void initializeFromClass( Class<?> c )
+ {
+ ModuleData data = c.getAnnotation( ModuleData.class );
+
+ if( data != null )
+ {
+ m_author = data.author();
+ m_minVersion = data.minVersion();
+ m_maxVersion = data.maxVersion();
+ m_scriptLocation = data.scripts();
+ m_stylesheetLocation = data.stylesheets();
+ m_adminBeanClass = data.adminBeanClass();
+ }
+ }
+
/**
* Returns the AdminBean class which is supposed to manage this module.
*
@@ -131,7 +147,7 @@
*
* @return The path to the location.
*/
- public String getStylesheetLocation()
+ public String[] getStylesheetLocation()
{
return m_stylesheetLocation;
}
@@ -141,7 +157,7 @@
*
* @return The path to the location.
*/
- public String getScriptLocation()
+ public String[] getScriptLocation()
{
return m_scriptLocation;
}
@@ -202,7 +218,7 @@
// Replace the 'PLUGIN_RESOURCE_LOCATION' with the requested
// resourceLocation.
- int length = ModuleManager.PLUGIN_RESOURCE_LOCATION.length();
+ int length = ModuleManager.MODULE_RESOURCE_LOCATION.length();
spec = spec.substring(0, spec.length() - length) + resourceLocation;
URL url = new URL(spec);
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/IfPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/IfPlugin.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/IfPlugin.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/IfPlugin.java Mon Nov 10 12:50:38 2008
@@ -25,6 +25,7 @@
import java.util.Map;
import org.apache.commons.lang.StringUtils;
+import org.apache.jspwiki.api.ModuleData;
import org.apache.oro.text.regex.*;
import com.ecyrd.jspwiki.TextUtil;
@@ -102,6 +103,7 @@
* @author Murray Altheim
* @since 2.6
*/
+@ModuleData( aliases = { "If" } )
public class IfPlugin implements WikiPlugin
{
/** The parameter name for setting the group to check. Value is <tt>{@value}</tt>. */
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/Image.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/Image.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/Image.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/Image.java Mon Nov 10 12:50:38 2008
@@ -21,6 +21,9 @@
package com.ecyrd.jspwiki.plugin;
import java.util.*;
+
+import org.apache.jspwiki.api.ModuleData;
+
import com.ecyrd.jspwiki.*;
import com.ecyrd.jspwiki.attachment.AttachmentManager;
import com.ecyrd.jspwiki.attachment.Attachment;
@@ -50,6 +53,9 @@
// FIXME: It is not yet possible to do wiki internal links. In order to
// do this cleanly, a TranslatorReader revamp is needed.
+@ModuleData(
+ author = "JSPWiki development group"
+)
public class Image
implements WikiPlugin
{
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/PluginManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/PluginManager.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/PluginManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/plugin/PluginManager.java Mon Nov 10 12:50:38 2008
@@ -21,19 +21,17 @@
package com.ecyrd.jspwiki.plugin;
import java.io.*;
-import java.net.URL;
import java.text.MessageFormat;
import java.util.*;
+import net.sourceforge.stripes.util.ResolverUtil;
+
import org.apache.commons.lang.ClassUtils;
import org.apache.ecs.xhtml.*;
+import org.apache.jspwiki.api.ModuleData;
import org.apache.log4j.Logger;
import org.apache.oro.text.regex.*;
-import org.jdom.Document;
import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.input.SAXBuilder;
-import org.jdom.xpath.XPath;
import com.ecyrd.jspwiki.*;
import com.ecyrd.jspwiki.modules.ModuleManager;
@@ -94,23 +92,29 @@
* <pre>
* [{Counter name='foo'}]
* </pre>
- * <h3>Plugin property files</h3>
+ * <h3>Plugin annotations</h3>
+ * <p>
+ * As of JSPWiki 3.0, plugins may be annotated using the ModuleData
+ * annotation. Please see the javadoc for ModuleData.
+ *
+ * <h3>Adding plugins to the automatic search path</h3>
+ * <p>
+ * You may add a plugin by defining a deployment file "ini/jspwiki_module.xml"
+ * with a single modules-element:
+ * <pre>
+ * <modules package="com.mycompany.plugins"/>
+ * </pre>
+ * This adds the plugin path "com.mycompany.plugins" in the list of
+ * packages which are searched for WikiPlugin instances.
* <p>
- * Since 2.3.25 you can also define a generic plugin XML properties file per
- * each JAR file.
+ * Another possibility is to use the <tt>jspwiki.plugin.searchPath</tt> -property.
+ * For example, the equivalent invocation to the previous example:
* <pre>
- * <modules>
- * <plugin class="com.ecyrd.jspwiki.foo.TestPlugin">
- * <author>Janne Jalkanen</author>
- * <script>foo.js</script>
- * <stylesheet>foo.css</stylesheet>
- * <alias>code</alias>
- * </plugin>
- * <plugin class="com.ecyrd.jspwiki.foo.TestPlugin2">
- * <author>Janne Jalkanen</author>
- * </plugin>
- * </modules>
+ * jspwiki.plugin.searchPath = com.mycompany.plugins
* </pre>
+ * However, this needs you to modify the property file by hand for each installation.
+ * It is a recommended practice to create a deployment file for your plugin JAR.
+ *
* <h3>Plugin lifecycle</h3>
*
* <p>Plugin can implement multiple interfaces to let JSPWiki know at which stages they should
@@ -147,11 +151,6 @@
private static final String DEFAULT_FORMS_PACKAGE = "com.ecyrd.jspwiki.forms";
/**
- * 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";
@@ -173,7 +172,7 @@
*/
public static final String PARAM_DEBUG = "debug";
- private ArrayList<String> m_searchPath = new ArrayList<String>();
+ private List<String> m_searchPath;
private Pattern m_pluginPattern;
@@ -194,19 +193,10 @@
public PluginManager( WikiEngine engine, Properties props )
{
super(engine);
- String packageNames = props.getProperty( PROP_SEARCHPATH );
- if( packageNames != null )
- {
- StringTokenizer tok = new StringTokenizer( packageNames, "," );
-
- while( tok.hasMoreTokens() )
- {
- m_searchPath.add( tok.nextToken().trim() );
- }
- }
-
- registerPlugins();
+ m_searchPath = buildPluginSearchPath( props );
+
+ registerAllPlugins();
//
// The default packages are always added.
@@ -278,7 +268,7 @@
*
* @throws ClassNotFoundException if no such class exists.
*/
- private Class findPluginClass( String classname )
+ private Class<? extends WikiPlugin> findPluginClass( String classname )
throws ClassNotFoundException
{
return ClassUtil.findClass( m_searchPath, classname );
@@ -614,7 +604,6 @@
* @return A DOM element
* @throws PluginException If plugin invocation is faulty
*/
- @SuppressWarnings("unchecked")
public PluginContent parsePluginLine( WikiContext context, String commandline, int pos )
throws PluginException
{
@@ -681,12 +670,15 @@
m_pluginClassMap.put(name, pluginClass);
}
- // Registrar the plugin with a short convenient name.
- name = pluginClass.getAlias();
- if(name != null)
+ // Register the plugin with a short convenient name.
+ String[] aliases = pluginClass.getAliases();
+ if(aliases != null)
{
- log.debug("Registering plugin [shortName]: " + name);
- m_pluginClassMap.put(name, pluginClass);
+ for( String a : aliases )
+ {
+ log.debug("Registering plugin [shortName]: " + a);
+ m_pluginClassMap.put(a, pluginClass);
+ }
}
// Registrar the plugin with the className with the package-part
@@ -700,61 +692,31 @@
pluginClass.initializePlugin( m_engine );
}
- private void registerPlugins()
+ private void registerAllPlugins()
{
log.info( "Registering plugins" );
- SAXBuilder builder = new SAXBuilder();
-
- try
+ //
+ // We locate every single class which implements the "WikiPlugin" interface.
+ //
+
+ ResolverUtil<WikiPlugin> resolver = new ResolverUtil<WikiPlugin>();
+
+ String[] paths = m_searchPath.toArray( new String[0] );
+ resolver.findImplementations( WikiPlugin.class, paths );
+
+ Set<Class<? extends WikiPlugin>> resultSet = resolver.getClasses();
+
+ log.debug( "Found "+resultSet.size()+" plugins" );
+
+ for( Class<? extends WikiPlugin> clazz : resultSet )
{
- //
- // Register all plugins which have created a resource containing its properties.
- //
- // Get all resources of all plugins.
- //
-
- Enumeration resources = getClass().getClassLoader().getResources( PLUGIN_RESOURCE_LOCATION );
+ WikiPluginInfo pluginInfo = WikiPluginInfo.newInstance( clazz );
- while( resources.hasMoreElements() )
+ if( pluginInfo != null )
{
- URL resource = (URL) resources.nextElement();
-
- try
- {
- log.debug( "Processing XML: " + resource );
-
- Document doc = builder.build( resource );
-
- List plugins = XPath.selectNodes( doc, "/modules/plugin");
-
- for( Iterator i = plugins.iterator(); i.hasNext(); )
- {
- Element pluginEl = (Element) i.next();
-
- String className = pluginEl.getAttributeValue("class");
-
- WikiPluginInfo pluginInfo = WikiPluginInfo.newInstance( className, pluginEl );
-
- if( pluginInfo != null )
- {
- registerPlugin( pluginInfo );
- }
- }
- }
- catch( java.io.IOException e )
- {
- log.error( "Couldn't load " + PLUGIN_RESOURCE_LOCATION + " resources: " + resource, e );
- }
- catch( JDOMException e )
- {
- log.error( "Error parsing XML for plugin: "+PLUGIN_RESOURCE_LOCATION );
- }
- }
- }
- catch( java.io.IOException e )
- {
- log.error( "Couldn't load all " + PLUGIN_RESOURCE_LOCATION + " resources", e );
+ registerPlugin( pluginInfo );
+ }
}
}
@@ -762,116 +724,62 @@
* Contains information about a bunch of plugins.
*
* @author Kees Kuip
- * @author Janne Jalkanen
- *
- * @since
*/
- // FIXME: This class needs a better interface to return all sorts of possible
- // information from the plugin XML. In fact, it probably should have
- // some sort of a superclass system.
public static final class WikiPluginInfo
extends WikiModuleInfo
{
- private String m_className;
- private String m_alias;
- private Class m_clazz;
-
- private boolean m_initialized = false;
-
- /**
- * Creates a new plugin info object which can be used to access a plugin.
- *
- * @param className Either a fully qualified class name, or a "short" name which is then
- * checked against the internal list of plugin packages.
- * @param el A JDOM Element containing the information about this class.
- * @return A WikiPluginInfo object.
- */
- protected static WikiPluginInfo newInstance( String className, Element el )
- {
- if( className == null || className.length() == 0 ) return null;
- WikiPluginInfo info = new WikiPluginInfo( className );
-
- info.initializeFromXML( el );
- return info;
- }
- /**
- * Initializes a plugin, if it has not yet been initialized.
- *
- * @param engine The WikiEngine
- */
- protected void initializePlugin( WikiEngine engine )
- {
- if( !m_initialized )
- {
- // This makes sure we only try once per class, even if init fails.
- m_initialized = true;
-
- try
- {
- WikiPlugin p = newPluginInstance();
- if( p instanceof InitializablePlugin )
- {
- ((InitializablePlugin)p).initialize( engine );
- }
- }
- catch( Exception e )
- {
- log.info( "Cannot initialize plugin "+m_className, e );
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void initializeFromXML( Element el )
- {
- super.initializeFromXML( el );
- m_alias = el.getChildText("alias");
- }
-
+ String[] m_aliases;
+ Class<? extends WikiPlugin> m_clazz;
+ boolean m_initialized = false;
+
/**
* Create a new WikiPluginInfo based on the Class information.
*
* @param clazz The class to check
* @return A WikiPluginInfo instance
*/
- protected static WikiPluginInfo newInstance( Class clazz )
+ protected static WikiPluginInfo newInstance( Class<? extends WikiPlugin> clazz )
{
- WikiPluginInfo info = new WikiPluginInfo( clazz.getName() );
+ WikiPluginInfo info = new WikiPluginInfo( clazz );
return info;
}
- private WikiPluginInfo( String className )
+ private WikiPluginInfo( Class<? extends WikiPlugin> clazz )
{
- super(className);
- setClassName( className );
+ super(clazz.getName());
+ setClassName( clazz.getName() );
+ initializeFromClass( clazz );
+ m_clazz = clazz;
+
+ ModuleData md = clazz.getAnnotation( ModuleData.class );
+ if( md != null )
+ {
+ m_aliases = md.aliases();
+ }
}
private void setClassName( String fullClassName )
{
m_name = ClassUtils.getShortClassName( fullClassName );
- m_className = fullClassName;
}
-
+
/**
* Returns the full class name of this object.
* @return The full class name of the object.
*/
public String getClassName()
{
- return m_className;
+ return m_clazz.getCanonicalName();
}
/**
* Returns the alias name for this object.
* @return An alias name for the plugin.
*/
- public String getAlias()
+ public String[] getAliases()
{
- return m_alias;
+ return m_aliases;
}
/**
@@ -887,12 +795,7 @@
InstantiationException,
IllegalAccessException
{
- if( m_clazz == null )
- {
- m_clazz = Class.forName(m_className);
- }
-
- return (WikiPlugin) m_clazz.newInstance();
+ return m_clazz.newInstance();
}
/**
@@ -938,7 +841,7 @@
try
{
- m_scriptText = getTextResource(m_scriptLocation);
+ m_scriptText = getTextResource(m_scriptLocation[0]);
}
catch( IOException ex )
{
@@ -965,7 +868,7 @@
try
{
- m_stylesheetText = getTextResource(m_stylesheetLocation);
+ m_stylesheetText = getTextResource(m_stylesheetLocation[0]);
}
catch( IOException ex )
{
@@ -978,6 +881,33 @@
}
/**
+ * Initializes a plugin, if it has not yet been initialized.
+ *
+ * @param engine The WikiEngine
+ */
+ protected void initializePlugin( WikiEngine engine )
+ {
+ if( !m_initialized )
+ {
+ // This makes sure we only try once per class, even if init fails.
+ m_initialized = true;
+
+ try
+ {
+ WikiPlugin p = newPluginInstance();
+ if( p instanceof InitializablePlugin )
+ {
+ ((InitializablePlugin)p).initialize( engine );
+ }
+ }
+ catch( Exception e )
+ {
+ log.info( "Cannot initialize plugin "+m_clazz.getCanonicalName(), e );
+ }
+ }
+ }
+
+ /**
* Returns a string suitable for debugging. Don't assume that the format
* would stay the same.
*
@@ -985,20 +915,20 @@
*/
public String toString()
{
- return "Plugin :[name=" + m_name + "][className=" + m_className + "]";
+ return "Plugin :[name=" + m_name + "][className=" + m_clazz.getCanonicalName() + "]";
}
} // WikiPluginClass
/**
* {@inheritDoc}
*/
- public Collection modules()
+ public Collection<WikiPluginInfo> modules()
{
- TreeSet<WikiModuleInfo> ls = new TreeSet<WikiModuleInfo>();
+ TreeSet<WikiPluginInfo> ls = new TreeSet<WikiPluginInfo>();
for( Iterator i = m_pluginClassMap.values().iterator(); i.hasNext(); )
{
- WikiModuleInfo wmi = (WikiModuleInfo)i.next();
+ WikiPluginInfo wmi = (WikiPluginInfo) i.next();
if( !ls.contains(wmi) ) ls.add(wmi);
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/EditorManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/EditorManager.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/EditorManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/EditorManager.java Mon Nov 10 12:50:38 2008
@@ -37,7 +37,6 @@
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.modules.ModuleManager;
import com.ecyrd.jspwiki.modules.WikiModuleInfo;
-import com.ecyrd.jspwiki.plugin.PluginManager;
import com.ecyrd.jspwiki.preferences.Preferences;
/**
@@ -123,7 +122,7 @@
// Get all resources of all modules
//
- Enumeration resources = getClass().getClassLoader().getResources( PLUGIN_RESOURCE_LOCATION );
+ Enumeration resources = getClass().getClassLoader().getResources( MODULE_RESOURCE_LOCATION );
while( resources.hasMoreElements() )
{
@@ -159,17 +158,17 @@
}
catch( java.io.IOException e )
{
- log.error( "Couldn't load " + PluginManager.PLUGIN_RESOURCE_LOCATION + " resources: " + resource, e );
+ log.error( "Couldn't load " + ModuleManager.MODULE_RESOURCE_LOCATION + " resources: " + resource, e );
}
catch( JDOMException e )
{
- log.error( "Error parsing XML for plugin: "+PluginManager.PLUGIN_RESOURCE_LOCATION );
+ log.error( "Error parsing XML for plugin: "+ModuleManager.MODULE_RESOURCE_LOCATION );
}
}
}
catch( java.io.IOException e )
{
- log.error( "Couldn't load all " + PLUGIN_RESOURCE_LOCATION + " resources", e );
+ log.error( "Couldn't load all " + MODULE_RESOURCE_LOCATION + " resources", e );
}
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/admin/beans/PluginBean.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/admin/beans/PluginBean.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/admin/beans/PluginBean.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/ui/admin/beans/PluginBean.java Mon Nov 10 12:50:38 2008
@@ -76,7 +76,7 @@
tr head = new tr();
head.addElement( new th("Name") );
- head.addElement( new th("Alias") );
+ head.addElement( new th("Aliases") );
head.addElement( new th("Author") );
head.addElement( new th("Notes") );
@@ -89,8 +89,16 @@
WikiPluginInfo info = i.next();
+ StringBuilder aliases = new StringBuilder();
+
+ for( String s : info.getAliases() )
+ {
+ if( aliases.length() > 0 ) aliases.append( ", " );
+ aliases.append( s );
+ }
+
row.addElement( new td(info.getName()) );
- row.addElement( new td(info.getAlias()) );
+ row.addElement( new td(aliases.toString()) );
row.addElement( new td(info.getAuthor()) );
String verWarning = "";
Modified: incubator/jspwiki/trunk/src/org/apache/jspwiki/api/ModuleData.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/org/apache/jspwiki/api/ModuleData.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/org/apache/jspwiki/api/ModuleData.java (original)
+++ incubator/jspwiki/trunk/src/org/apache/jspwiki/api/ModuleData.java Mon Nov 10 12:50:38 2008
@@ -65,13 +65,13 @@
* Defines the style sheets which should be included whenever this module
* is used. For PageFilters this means almost every single request.
*/
- String[] stylesheets() default {};
+ String[] stylesheets() default "";
/**
* Defines the Javascripts which should be included whenever this module
* is used.
*/
- String[] scripts() default {};
+ String[] scripts() default "";
/**
* Returns the class name for the AdminBean which governs the use of this
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/PluginManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/PluginManagerTest.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/PluginManagerTest.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/PluginManagerTest.java Mon Nov 10 12:50:38 2008
@@ -1,6 +1,7 @@
package com.ecyrd.jspwiki.plugin;
+import java.util.Collection;
import java.util.Properties;
import junit.framework.Test;
@@ -11,6 +12,7 @@
import com.ecyrd.jspwiki.WikiContext;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.plugin.PluginManager.WikiPluginInfo;
import com.ecyrd.jspwiki.providers.ProviderException;
public class PluginManagerTest extends TestCase
@@ -198,6 +200,28 @@
assertTrue( SamplePlugin.c_rendered );
}
+ public void testAnnotations() throws Exception
+ {
+ Collection<WikiPluginInfo> plugins = manager.modules();
+
+ for( WikiPluginInfo wpi : plugins )
+ {
+ if( wpi.getName().equals( "SamplePlugin" ) )
+ {
+ assertEquals("author", "Urgle Burgle", wpi.getAuthor());
+ String[] aliases = wpi.getAliases();
+
+ assertNotNull("aliases",aliases);
+ assertEquals( "aliases len", 2, aliases.length );
+ assertTrue( "data", ( aliases[0].equals( "samplealias2" ) && aliases[1].equals( "samplealias" ) )
+ || (aliases[0].equals("samplealias") && aliases[1].equals("samplealias2")) );
+ return; // We're done
+ }
+ }
+
+ fail("No SamplePlugin found");
+ }
+
public static Test suite()
{
return new TestSuite( PluginManagerTest.class );
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/SamplePlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/SamplePlugin.java?rev=712830&r1=712829&r2=712830&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/SamplePlugin.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/plugin/SamplePlugin.java Mon Nov 10 12:50:38 2008
@@ -2,6 +2,8 @@
import java.util.Map;
+import org.apache.jspwiki.api.ModuleData;
+
import com.ecyrd.jspwiki.WikiContext;
import com.ecyrd.jspwiki.parser.PluginContent;
@@ -10,9 +12,9 @@
* <P>
* Parameters: text - text to return.
* Any _body content gets appended between brackets.
- *
- * @author Janne Jalkanen
*/
+@ModuleData( author = "Urgle Burgle",
+ aliases = { "samplealias2", "samplealias" } )
public class SamplePlugin
implements WikiPlugin, ParserStagePlugin
{