You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2008/02/13 06:54:24 UTC

svn commit: r627255 [27/41] - in /incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src: ./ com/ com/ecyrd/ com/ecyrd/jspwiki/ com/ecyrd/jspwiki/action/ com/ecyrd/jspwiki/attachment/ com/ecyrd/jspwiki/auth/ com/ecyrd/jspwiki/auth/acl/ com/ecyrd/jspwiki...

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_en.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_en.properties?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_en.properties (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_en.properties Tue Feb 12 21:53:55 2008
@@ -0,0 +1,56 @@
+# This is the English language bundle for JSPWiki core plugins
+# Don't add your own plugins to this file; create your own bundle, please.
+
+# Common things
+
+# Date format used across JSPWiki.  Please see "SimpleDateFormat" on information
+# how to handle this
+
+common.dateformat = HH:mm:ss dd-MMM-yyyy zzzz
+
+# Errors rendering plugins
+
+plugin.error.insertionfailed = Plugin insertion failed: {0}
+plugin.error.cannotinstantiate = Cannot instantiate plugin {0} 
+plugin.error.notallowed = Not allowed to access plugin {0}
+plugin.error.instantationfailed = Instantiation of plugin {0} failed.
+plugin.error.failed = Plugin failed
+plugin.error.couldnotfind = Could not find plugin {0}
+plugin.error.notawikiplugin = Class {0} is not a Wiki plugin.
+plugin.error.missingparameter = Missing parameter in plugin definition: {0}
+plugin.error.parsingarguments = Zyrf.  Problems with parsing arguments: {0}
+
+# TableOfContents
+tableofcontents.title = Table of Contents
+
+# BugReportHandler
+
+bugreporthandler.new = A new page has been created: {0}
+bugreporthandler.unable = Unable to create a new page!
+bugreporthandler.titlerequired = Title is required!
+
+# CurrentTimePlugin
+
+currenttimeplugin.badformat = You specified a bad format
+
+# WeblogEntryPlugin
+
+weblogentryplugin.newentry = New entry
+
+# ReferringPagesPlugin
+
+# This is in JSPWikiMarkup; {0} is where you put in the number, {1} is an URL
+referringpagesplugin.more = ...and [{0} more|{1}]\\\\
+referringpagesplugin.nobody = ...nobody
+
+# Forms plugins
+formclose.noneedtoshow = (no need to show close now)
+forminput.namemissing = Input element is missing parameter 'name'.
+forminput.noneedtoshow = (no need to show input field now)
+formopen.missingparam = The FormOpen element is missing the '{0}' parameter.
+formopen.postorgetonly = Method must be either 'post' or 'get'
+formopen.noneedtoshow = (no need to show form open now)
+formoutput.missingargument = Argument '{0}' required for Form plugin
+formselect.namemissing = Select element is missing parameter 'name'.
+formtextarea.noneedtoshow = (no need to show textarea field now)
+formtextarea.namemissing = Textarea element is missing parameter 'name'.
\ No newline at end of file

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_es.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_es.properties?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_es.properties (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_es.properties Tue Feb 12 21:53:55 2008
@@ -0,0 +1,56 @@
+# This is the English language bundle for JSPWiki core plugins
+# Don't add your own plugins to this file; create your own bundle, please.
+
+# Common things
+
+# Date format used across JSPWiki.  Please see "SimpleDateFormat" on information
+# how to handle this
+
+common.dateformat = dd-MMM-yyyy zzzz HH:mm:ss
+
+# Errors rendering plugins
+
+plugin.error.insertionfailed = Fallo en la inserción del Plugin: {0}
+plugin.error.cannotinstantiate = No se pudo instantiar el plugin {0} 
+plugin.error.notallowed = No está permitido el acceso al plugin {0}
+plugin.error.instantationfailed = La instanciación del plugin {0} ha fallado.
+plugin.error.failed = El plugin ha fallado
+plugin.error.couldnotfind = No se pudo encontrar el plugin {0}
+plugin.error.notawikiplugin = La clase {0} no es un plugin del Wiki.
+plugin.error.missingparameter = Parámetro faltante en la definición del plugin: {0}
+plugin.error.parsingarguments = Zyrf.  Problemas al parsear los argumentos: {0}
+
+# TableOfContents
+tableofcontents.title = Tabla de Contenidos
+
+# BugReportHandler
+
+bugreporthandler.new = Se ha creado un nuevo informe de errores: {0}
+bugreporthandler.unable = ¡No se pudo crear el nuevo informe de errores!
+bugreporthandler.titlerequired = ¡El título es obligatorio!
+
+# CurrentTimePlugin
+
+currenttimeplugin.badformat = Especificaste un formato erróneo
+
+# WeblogEntryPlugin
+
+weblogentryplugin.newentry = Nueva entrada
+
+# ReferringPagesPlugin
+
+# This is in JSPWikiMarkup; {0} is where you put in the number
+referringpagesplugin.more = ... y [{0} más|{1}]\\\\
+referringpagesplugin.nobody = ...nadie
+
+# Forms plugins
+formclose.noneedtoshow = (no es necesario mostrar el cierre ahora)
+forminput.namemissing = El elemento campo de entrada no tiene definido el parámetro 'name'.
+forminput.noneedtoshow = (no es necesario mostrar el campo de entrada de texto ahora)
+formopen.missingparam = El elemento FormOpen no tiene definido el parámetro '{0}'.
+formopen.postorgetonly = El atributo 'Method' debe ser obligatoriamente 'post' o 'get'
+formopen.noneedtoshow = (no es necesario mostrar la apertura del form ahora)
+formoutput.missingargument = El argumento '{0}' es requerido por el plugin Form
+formselect.namemissing = El elemento Select no tiene definido el parámetro 'name'.
+formtextarea.noneedtoshow = (no es necesario mostrar el campo textarea ahora)
+formtextarea.namemissing = El elemento Textarea no tiene definido el parámetro 'name'.

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_fi.properties
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_fi.properties?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_fi.properties (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/PluginResources_fi.properties Tue Feb 12 21:53:55 2008
@@ -0,0 +1,45 @@
+# This is the English language bundle for JSPWiki core plugins
+# Don't add your own plugins to this file; create your own bundle, please.
+
+# Common things
+
+# Date format used across JSPWiki.  Please see "SimpleDateFormat" on information
+# how to handle this
+
+common.dateformat = HH:mm:ss dd-MMM-yyyy zzzz
+
+# TableOfContents
+tableofcontents.title = Sisällysluettelo
+
+# BugReportHandler
+
+bugreporthandler.new = Uusi raportti on luotu
+bugreporthandler.unable = Ei voinut luoda uutta raporttia
+bugreporthandler.titlerequired = Otsikko on pakollinen
+
+# CurrentTimePlugin
+
+currenttimeplugin.badformat = Viallinen formaatti
+
+# WeblogEntryPlugin
+
+weblogentryplugin.newentry = Uusi merkintä
+
+# ReferringPagesPlugin
+
+# This is in JSPWikiMarkup; {0} is where you put in the number, and {1} is a link
+# to the page info with the full list
+referringpagesplugin.more = ...ja [{0} lisää|{1}]\\\\
+referringpagesplugin.nobody = ...ei kukaan
+
+# Forms Plugins
+formclose.noneedtoshow = (ei tarvetta näyttää suljettuja nyt)
+forminput.namemissing = FormInput tarvitsee parameterin 'name'.
+forminput.noneedtoshow = (ei tarvetta näyttää piilotettuja elementtejä)
+formopen.missingparam = FormOpen tarvitsee parameterin '{0}'.
+formopen.postorgetonly = Method-parametrin on oltava joko 'post' or 'get'.
+formopen.noneedtoshow = (ei tarvetta näyttää avattua formia)
+formoutput.missingargument = FormOutput tarvitsee parametrin '{0}'.
+formselect.namemissing = Select tarvitsee parametrin 'name'.
+formtextarea.noneedtoshow = (ei tarvetta näyttää tekstinsyöttökenttää)
+formtextarea.namemissing = TextArea-elementti tarvitsee parametrin 'name'.

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RPCSamplePlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RPCSamplePlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RPCSamplePlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RPCSamplePlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,59 @@
+/* 
+    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.plugin;
+
+import java.util.Map;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.rpc.RPCCallable;
+import com.ecyrd.jspwiki.rpc.json.JSONRPCManager;
+
+/**
+ *  Simple plugin which shows how to add JSON calls to your plugin.
+ * 
+ *  @author Janne Jalkanen
+ *  @since  2.5.4
+ */
+public class RPCSamplePlugin implements WikiPlugin, RPCCallable
+{  
+    /**
+     *  This method is called when the Javascript is encountered by
+     *  the browser.
+     *  @param echo
+     *  @return the string <code>JSON says:</code>, plus the value 
+     *  supplied by the <code>echo</code> parameter
+     */
+    public String myFunction(String echo)
+    {
+        return "JSON says: "+echo;
+    }
+    
+
+    
+    public String execute(WikiContext context, Map params) throws PluginException
+    {
+        JSONRPCManager.registerJSONObject( context, this );
+        
+        String s = JSONRPCManager.emitJSONCall( context, this, "myFunction", "'foo'" );
+        
+        return s;
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RecentChangesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RecentChangesPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RecentChangesPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/RecentChangesPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,265 @@
+/* 
+    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 java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import org.apache.ecs.xhtml.*;
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.TextUtil;
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiPage;
+import com.ecyrd.jspwiki.action.*;
+import com.ecyrd.jspwiki.attachment.Attachment;
+
+/**
+ *  Returns the Recent Changes.
+ *
+ *  Parameters: since=number of days,
+ *              format=(compact|full)
+ *
+ *  @author Janne Jalkanen
+ */
+public class RecentChangesPlugin
+    implements WikiPlugin
+{
+    private static final String PARAM_FORMAT = "format";
+    private static final String PARAM_TIME_FORMAT = "timeFormat";
+    private static final String PARAM_DATE_FORMAT = "dateFormat";
+
+    /** How many days we show by default. */
+    private static final int    DEFAULT_DAYS = 100*365;
+
+    private static Logger log = Logger.getLogger( RecentChangesPlugin.class );
+
+    private boolean isSameDay( Date a, Date b )
+    {
+        Calendar aa = Calendar.getInstance(); aa.setTime(a);
+        Calendar bb = Calendar.getInstance(); bb.setTime(b);
+
+        return aa.get( Calendar.YEAR ) == bb.get( Calendar.YEAR ) &&
+                aa.get( Calendar.DAY_OF_YEAR ) == bb.get( Calendar.DAY_OF_YEAR );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        int      since    = TextUtil.parseIntParameter( (String) params.get("since"),
+                                                        DEFAULT_DAYS );
+        int      spacing  = 4;
+        boolean  showAuthor = true;
+        boolean  showChangenote = true;
+        int      tablewidth = 4;
+        
+        WikiEngine engine = context.getEngine();
+
+        //
+        //  Which format we want to see?
+        //
+        if( "compact".equals( params.get(PARAM_FORMAT) ) )
+        {
+            spacing  = 0;
+            showAuthor = false;
+            showChangenote = false;
+            tablewidth = 2;
+        }
+
+        Calendar sincedate = new GregorianCalendar();
+        sincedate.add( Calendar.DAY_OF_MONTH, -since );
+
+        log.debug("Calculating recent changes from "+sincedate.getTime());
+
+        // FIXME: Should really have a since date on the getRecentChanges
+        // method.
+        Collection   changes = engine.getRecentChanges();
+
+        if( changes != null )
+        {
+            Date olddate   = new Date(0);
+
+            DateFormat fmt = getDateFormat(params);
+            DateFormat tfmt = getTimeFormat(params);
+
+            table rt = new table();
+            rt.setCellPadding(spacing).setClass("recentchanges");
+
+            for( Iterator i = changes.iterator(); i.hasNext(); )
+            {
+                WikiPage pageref = (WikiPage) i.next();
+
+                Date lastmod = pageref.getLastModified();
+
+                if( lastmod.before( sincedate.getTime() ) )
+                {
+                    break;
+                }
+                
+                if( !isSameDay( lastmod, olddate ) )
+                {
+                    tr row = new tr();
+                    td col = new td();
+                    
+                    col.setColSpan(tablewidth).setClass("date"); 
+                    col.addElement( new b().addElement(fmt.format(lastmod)) );
+
+                    rt.addElement(row);
+                    row.addElement(col);                    
+                    olddate = lastmod;
+                }
+
+                String link = context.getContext().getURL( pageref instanceof Attachment ? AttachActionBean.class : ViewActionBean.class, 
+                                              pageref.getName() ) ;
+                
+                a linkel = new a(link,engine.beautifyTitle(pageref.getName()));
+                
+                tr row = new tr();
+                
+                td col = new td().setWidth("30%").addElement(linkel);
+
+                //
+                //  Add the direct link to the attachment info.
+                //
+                if( pageref instanceof Attachment )
+                {
+                    linkel = new a().setHref(context.getContext().getURL(PageInfoActionBean.class,pageref.getName()));
+                    linkel.addElement( new img().setBorder(0).setSrc(context.getContext().getURL(NoneActionBean.class, "images/attachment_small.png")));
+
+                    col.addElement( linkel );
+                }
+
+                
+                row.addElement(col);
+                rt.addElement(row);
+                
+                if( pageref instanceof Attachment )
+                {
+                    row.addElement( new td(tfmt.format(lastmod)).setClass("lastchange") );
+                }
+                else
+                {
+                    td infocol = (td) new td().setClass("lastchange");
+                    Map<String,String> urlParams = new HashMap<String,String>();
+                    urlParams.put("r1", "-1");
+                    infocol.addElement( new a(context.getContext().getURL(DiffActionBean.class, pageref.getName(), urlParams),tfmt.format(lastmod)) );
+                    row.addElement(infocol);
+                }
+
+                //
+                //  Display author information.
+                //
+
+                if( showAuthor )
+                {
+                    String author = pageref.getAuthor();
+
+                    td authorinfo = new td();
+                    authorinfo.setClass("author");
+                    
+                    if( author != null )
+                    {
+                        if( engine.pageExists(author) )
+                        {
+                            authorinfo.addElement( new a(context.getContext().getURL(ViewActionBean.class, author),author) );
+                        }
+                        else
+                        {
+                            authorinfo.addElement(author);
+                        }
+                    }
+                    else
+                    {
+                        authorinfo.addElement("unknown");
+                    }
+
+                    row.addElement( authorinfo );
+                }
+
+                // Change note
+                if( showChangenote )
+                {
+                    String changenote = (String)pageref.getAttribute(WikiPage.CHANGENOTE);
+                    
+                    row.addElement( new td(changenote != null ? TextUtil.replaceEntities(changenote) : "").setClass("changenote") );
+                }
+                
+                //  Revert note
+/*                
+                if( context.hasAdminPermissions() )
+                {
+                    row.addElement( new td("Revert") );
+                }
+ */
+            }
+
+            rt.setPrettyPrint(true);
+            return rt.toString();
+        }
+        
+        return "";
+    }
+
+    
+
+    // TODO: Ideally the default behavior should be to return the default format for the default
+    // locale, but that is at odds with the 1st version of this plugin. We seek to preserve the
+    // behaviour of that first version, so to get the default format, the user must explicitly do
+    // something like: dateFormat='' timeformat='' which is a odd, but probably okay.
+    private DateFormat getTimeFormat(Map params)
+    {
+        String formatString = get(params, "HH:mm:ss", PARAM_TIME_FORMAT);
+
+        if ("".equals(formatString.trim()))
+            return SimpleDateFormat.getTimeInstance();
+
+        return new SimpleDateFormat(formatString);
+    }
+
+
+
+    private DateFormat getDateFormat(Map params)
+    {
+        String formatString = get(params, "dd.MM.yyyy", PARAM_DATE_FORMAT);
+
+        if ("".equals(formatString.trim()))
+            return SimpleDateFormat.getDateInstance();
+
+        return new SimpleDateFormat(formatString);
+
+    }
+
+
+
+    private String get(Map params, String defaultValue, String paramName)
+    {
+        String value = (String) params.get(paramName);
+        return null == value ? defaultValue : value;
+    }
+
+    
+}
+
+

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferredPagesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferredPagesPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferredPagesPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferredPagesPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,234 @@
+/*
+        ReferredPagesPlugin
+        Dirk Frederickx Aug 2004, Jan 2005
+        Janne Jalkanen 2005
+
+        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;
+
+/**
+ *  Displays the pages referring to the current page.
+ *
+ *  <P>Parameters</P>
+ *  <UL>
+ *    <LI>name:    Name of the root page. Default name of calling page
+ *    <LI>type:    local|externalattachment
+ *    <LI>depth:   How many levels of pages to be parsed.
+ *    <LI>include: Include only these pages. (eg. include='UC.*|BP.*' )
+ *    <LI>exclude: Exclude with this pattern. (eg. exclude='LeftMenu' )
+ *    <LI>format:  full|compact
+ *        <br>FULL now expands all levels correctly
+ *  </UL>
+ *
+ *  @author Dirk Frederickx
+ */
+
+import java.util.*;
+
+import org.apache.log4j.Logger;
+import org.apache.oro.text.regex.*;
+
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.action.ViewActionBean;
+
+public class ReferredPagesPlugin implements WikiPlugin
+{
+    private static Logger log = Logger.getLogger( ReferredPagesPlugin.class );
+    private WikiEngine     m_engine;
+    private int            m_depth;
+    private HashSet        m_exists  = new HashSet();
+    private StringBuffer   m_result  = new StringBuffer(1024);
+    private PatternMatcher m_matcher = new Perl5Matcher();
+    private Pattern        m_includePattern;
+    private Pattern        m_excludePattern;
+    private boolean m_formatCompact  = true;
+    private boolean m_formatSort     = false;
+
+    public static final String PARAM_ROOT    = "page";
+    public static final String PARAM_DEPTH   = "depth";
+    public static final String PARAM_TYPE    = "type";
+    public static final String PARAM_INCLUDE = "include";
+    public static final String PARAM_EXCLUDE = "exclude";
+    public static final String PARAM_FORMAT  = "format";
+    public static final int    MIN_DEPTH = 1;
+    public static final int    MAX_DEPTH = 8;
+
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        m_engine = context.getEngine();
+
+        WikiPage         page   = context.getPage();
+        if( page == null ) return "";
+
+        // parse parameters
+        String rootname = (String)params.get( PARAM_ROOT );
+        if( rootname == null ) rootname = page.getName() ;
+
+        String format = (String)params.get( PARAM_FORMAT );
+        if( format == null) format = "";
+        if( format.indexOf( "full" ) >=0 ) m_formatCompact = false ;
+        if( format.indexOf( "sort" ) >=0 ) m_formatSort    = true  ;
+
+        m_depth = TextUtil.parseIntParameter( (String)params.get( PARAM_DEPTH ), MIN_DEPTH );
+        if( m_depth > MAX_DEPTH )  m_depth = MAX_DEPTH;
+
+        String includePattern = (String) params.get(PARAM_INCLUDE);
+        if( includePattern == null ) includePattern = ".*";
+
+        String excludePattern = (String) params.get(PARAM_EXCLUDE);
+        if( excludePattern == null ) excludePattern = "^$";
+
+        log.debug( "Fetching referred pages for "+ rootname +
+                   " with a depth of "+ m_depth +
+                   " with include pattern of "+ includePattern +
+                   " with exclude pattern of "+ excludePattern );
+
+        //
+        // do the actual work
+        //
+        String href  = context.getViewURL(rootname);
+        String title = "ReferredPagesPlugin: depth["+m_depth+
+                       "] include["+includePattern+"] exclude["+excludePattern+
+                       "] format["+(m_formatCompact ? "compact" : "full") +
+                       (m_formatSort ? " sort" : "") + "]";
+
+        m_result.append("<div class=\"ReferredPagesPlugin\">\n");
+        m_result.append("<a class=\"wikipage\" href=\""+ href +
+                        "\" title=\"" + title +
+                        "\">" + rootname + "</a>\n");
+        m_exists.add(rootname);
+
+        // pre compile all needed patterns
+        // glob compiler :  * is 0..n instance of any char  -- more convenient as input
+        // perl5 compiler : .* is 0..n instances of any char -- more powerful
+        //PatternCompiler g_compiler = new GlobCompiler();
+        PatternCompiler compiler = new Perl5Compiler();
+
+        try
+        {
+            m_includePattern = compiler.compile(includePattern);
+
+            m_excludePattern = compiler.compile(excludePattern);
+        }
+        catch( MalformedPatternException e )
+        {
+            if (m_includePattern == null )
+            {
+                throw new PluginException("Illegal include pattern detected.");
+            }
+            else if (m_excludePattern == null )
+            {
+                throw new PluginException("Illegal exclude pattern detected.");
+            }
+            else
+            {
+                throw new PluginException("Illegal internal pattern detected.");
+            }
+        }
+
+        // go get all referred links
+        getReferredPages(context,rootname, 0);
+
+        // close and finish
+        m_result.append ("</div>\n" ) ;
+
+        return m_result.toString() ;
+    }
+
+
+    /**
+     * Retrieves a list of all referred pages. Is called recursively
+     * depending on the depth parameter
+     */
+    protected void getReferredPages( WikiContext context, String pagename, int depth )
+    {
+        if( depth >= m_depth ) return;  // end of recursion
+        if( pagename == null ) return;
+        if( !m_engine.pageExists(pagename) ) return;
+
+        ReferenceManager mgr = m_engine.getReferenceManager();
+
+        Collection allPages = mgr.findRefersTo( pagename );
+
+        handleLinks( context, allPages, ++depth, pagename );
+    }
+
+    protected void handleLinks(WikiContext context,Collection links, int depth, String pagename)
+    {
+        boolean isUL = false;
+        HashSet localLinkSet = new HashSet();  // needed to skip multiple
+        // links to the same page
+        localLinkSet.add(pagename);
+
+        ArrayList allLinks = new ArrayList();
+
+        if( links != null )
+            allLinks.addAll( links );
+
+        if( m_formatSort ) Collections.sort(allLinks);
+
+        for( Iterator i = allLinks.iterator(); i.hasNext(); )
+        {
+            String link = (String) i.next() ;
+
+            if( localLinkSet.contains( link ) ) continue; // skip multiple
+                                                          // links to the same
+                                                          // page
+            localLinkSet.add( link );
+
+            if( !m_engine.pageExists( link ) ) continue; // hide links to non
+                                                         // existing pages
+
+            if(  m_matcher.matches( link , m_excludePattern ) ) continue;
+            if( !m_matcher.matches( link , m_includePattern ) ) continue;
+
+            if( m_exists.contains( link ) )
+            {
+                if( !m_formatCompact )
+                {
+                    if( !isUL )
+                    {
+                        isUL = true; m_result.append("<ul>\n");
+                    }
+
+                    m_result.append("<li> " + link + " </li>\n");
+
+                    getReferredPages( context, link, depth );  // added recursive
+                                                      // call - on general
+                                                      // request
+                }
+            }
+            else
+            {
+                if( !isUL )
+                {
+                    isUL = true; m_result.append("<ul>\n");
+                }
+
+                String href = context.getContext().getURL(ViewActionBean.class,link);  
+                m_result.append("<li><a class=\"wikipage\" href=\""+ href +"\">"+link+"</a></li>\n" );
+
+                m_exists.add( link );
+
+                getReferredPages( context, link, depth );
+            }
+        }
+
+        if( isUL ) m_result.append("</ul>\n");
+    }
+}
+

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferringPagesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferringPagesPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferringPagesPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/ReferringPagesPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,110 @@
+/* 
+    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.plugin;
+
+import org.apache.log4j.Logger;
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.action.PageInfoActionBean;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ *  Displays the pages referring to the current page.
+ *
+ *  Parameters: <BR>
+ *  max: How many items to show.<BR>
+ *  extras: How to announce extras.<BR>
+ *  From AbstractReferralPlugin:<BR>
+ *  separator: How to separate generated links; default is a wikitext line break,
+ *             producing a vertical list.<BR>
+ *  maxwidth: maximum width, in chars, of generated links.
+ *
+ *  @author Janne Jalkanen
+ */
+public class ReferringPagesPlugin
+    extends AbstractReferralPlugin
+{
+    private static Logger log = Logger.getLogger( ReferringPagesPlugin.class );
+
+    public static final String PARAM_MAX      = "max";
+    public static final String PARAM_EXTRAS   = "extras";
+    public static final String PARAM_PAGE     = "page";
+    
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        ReferenceManager refmgr = context.getEngine().getReferenceManager();
+        String pageName = (String)params.get( PARAM_PAGE );
+        ResourceBundle rb = context.getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
+        
+        if( pageName == null )
+        {
+            pageName = context.getPage().getName();
+        }
+
+        WikiPage page = context.getEngine().getPage( pageName );
+        
+        if( page != null )
+        {
+            Collection   links  = refmgr.findReferrers( page.getName() );
+            String       wikitext = "";
+
+            super.initialize( context, params );
+
+            int items = TextUtil.parseIntParameter( (String)params.get( PARAM_MAX ), ALL_ITEMS );
+            String extras = (String)params.get( PARAM_EXTRAS );
+            if( extras == null )
+            {
+                extras = rb.getString("referringpagesplugin.more");
+            }
+            
+            log.debug( "Fetching referring pages for "+page.getName()+
+                       " with a max of "+items);
+        
+            if( links != null && links.size() > 0 )
+            {
+                links = filterCollection( links );
+                wikitext = wikitizeCollection( links, m_separator, items );
+
+                if( items < links.size() && items > 0 )
+                {
+                    Object[] args = { "" + ( links.size() - items),
+                                      context.getContext().getURL( PageInfoActionBean.class, page.getName() ) };
+                    extras = MessageFormat.format(extras, args); 
+                    wikitext += extras;
+                }
+            }
+
+            //
+            //  If nothing was left after filtering or during search
+            //
+            if( links == null || links.size() == 0 )
+            {
+                wikitext = rb.getString("referringpagesplugin.nobody");
+            }
+
+            return makeHTML( context, wikitext );
+        }
+
+        return "";
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/Search.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/Search.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/Search.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/Search.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,143 @@
+/* 
+   JSPWiki - a JSP-based WikiWiki clone.
+
+   Copyright (C) 2005 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 java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.ecs.xhtml.*;
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.SearchResult;
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.action.ViewActionBean;
+import com.ecyrd.jspwiki.providers.ProviderException;
+
+/**
+ *  @author jalkanen
+ *
+ *  @since 
+ */
+public class Search implements WikiPlugin
+{
+    static Logger log = Logger.getLogger(Search.class);
+    
+    public static final String PARAM_QUERY = "query";
+    public static final String PARAM_SET   = "set";
+    public static final String DEFAULT_SETNAME = "_defaultSet";
+    public static final String PARAM_MAX   = "max";
+    
+    /* (non-Javadoc)
+     * @see com.ecyrd.jspwiki.plugin.WikiPlugin#execute(com.ecyrd.jspwiki.WikiContext, java.util.Map)
+     */
+    public String execute( WikiContext context, Map params ) throws PluginException
+    {
+        int maxItems = Integer.MAX_VALUE;
+        Collection results = null;
+        
+        String queryString = (String)params.get( PARAM_QUERY );
+        String set         = (String)params.get( PARAM_SET );
+        String max         = (String)params.get( PARAM_MAX );
+        
+        if( set == null ) set = DEFAULT_SETNAME;
+        if( max != null ) maxItems = Integer.parseInt( max );
+        
+        if( queryString == null )
+        {
+            results = (Collection)context.getVariable( set );
+        }
+        else
+        {
+            try
+            {
+                results = doBasicQuery( context, queryString );
+                context.setVariable( set, results );
+            }
+            catch( Exception e )
+            {
+                return "<div class='error'>"+e.getMessage()+"</div>\n";
+            }
+        }
+        
+        String res = "";
+        
+        if( results != null )
+        {
+            res = renderResults( results, context, maxItems );
+        }
+        
+        return res;
+    }
+    
+    private Collection doBasicQuery( WikiContext context, String query )
+        throws ProviderException, IOException
+    {
+        log.debug("Searching for string "+query);
+
+        Collection list = context.getEngine().findPages( query );
+
+        return list;
+    }
+    
+    private String renderResults( Collection results, WikiContext context, int maxItems )
+    {
+        WikiEngine engine = context.getEngine();
+        table t = new table();
+        t.setBorder(0);
+        t.setCellPadding(4);
+
+        tr row = new tr();
+        t.addElement( row );
+        
+        row.addElement( new th().setWidth("30%").setAlign("left").addElement("Page") );
+        row.addElement( new th().setAlign("left").addElement("Score"));
+
+        int idx = 0;
+        for( Iterator i = results.iterator(); i.hasNext() && idx++ <= maxItems; )
+        {
+            SearchResult sr = (SearchResult) i.next();
+            row = new tr();
+            
+            td name = new td().setWidth("30%");
+            name.addElement( "<a href=\""+
+                             context.getContext().getURL( ViewActionBean.class, sr.getPage().getName() )+
+                             "\">"+engine.beautifyTitle(sr.getPage().getName())+"</a>");
+            row.addElement( name );
+            
+            row.addElement( new td().addElement(""+sr.getScore()));
+            
+            t.addElement( row );
+        }
+        
+        if( results.isEmpty() )
+        {
+            row = new tr();
+            
+            row.addElement( new td().setColSpan(2).addElement( new b().addElement("No results")));
+
+            t.addElement(row);
+        }
+        
+        return t.toString();
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/SessionsPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/SessionsPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/SessionsPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/SessionsPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,111 @@
+/* 
+    JSPWiki - a JSP-based WikiWiki clone.
+
+    Copyright (C) 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.plugin;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.ecyrd.jspwiki.WikiContext;
+import com.ecyrd.jspwiki.WikiEngine;
+import com.ecyrd.jspwiki.WikiSession;
+
+/**
+ *  <p>Displays information about active wiki sessions. The parameter
+ *  <code>property</code> specifies what information is displayed.
+ *  If omitted, the number of sessions is returned.
+ *  Valid values for the <code>property</code> parameter
+ *  include:</p>
+ *  <ul>
+ *    <li><code>users</code> - returns a comma-separated list of
+ *    users</li>
+ *    <li><code>distinctUsers</code> - will only show
+ *    distinct users.
+ *  </ul>
+ *  @since 2.3.84
+ *  @author Andrew Jaquith
+ */
+public class SessionsPlugin
+    implements WikiPlugin
+{
+    public static final String PARAM_PROP = "property";
+    
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        WikiEngine engine = context.getEngine();
+        String prop = (String) params.get( PARAM_PROP );
+        
+        if ( "users".equals( prop ) )
+        {
+            Principal[] principals = WikiSession.userPrincipals( engine );
+            StringBuffer s = new StringBuffer();
+            for ( int i = 0; i < principals.length; i++ )
+            {
+                s.append(principals[i].getName() + ", ");
+            }
+            // remove the last comma and blank :
+            return s.substring(0, s.length() - (s.length() > 2 ? 2 : 0) );
+        }
+
+        //
+        // show each user session only once (with a counter that indicates the
+        // number of sessions for each user)
+        if ("distinctUsers".equals(prop))
+        {
+            Principal[] principals = WikiSession.userPrincipals(engine);
+            // we do not assume that the principals are sorted, so first count
+            // them :
+            HashMap distinctPrincipals = new HashMap();
+            for (int i = 0; i < principals.length; i++)
+            {
+                String principalName = principals[i].getName();
+
+                if (distinctPrincipals.containsKey(principalName))
+                {
+                    // we already have an entry, increase the counter:
+                    int numSessions = ((Integer) distinctPrincipals.get(principalName)).intValue();
+                    // store the new value:
+                    distinctPrincipals.put(principalName, new Integer(++numSessions));
+                }
+                else
+                {
+                    // first time we see this entry, add entry to HashMap with
+                    // value 1
+                    distinctPrincipals.put(principalName, new Integer(1));
+                }
+            }
+            //
+            //
+            StringBuffer s = new StringBuffer();
+            Iterator entries = distinctPrincipals.entrySet().iterator();
+            while (entries.hasNext())
+            {
+                Map.Entry entry = (Map.Entry)entries.next();
+                s.append((entry.getKey().toString() + "(" + entry.getValue().toString() + "), "));
+            }
+            // remove the last comma and blank :
+            return s.substring(0, s.length() - 2);
+        }
+
+        return String.valueOf( WikiSession.sessions( engine ) );
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/TableOfContents.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/TableOfContents.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/TableOfContents.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/TableOfContents.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,225 @@
+/*
+    JSPWiki - a JSP-based WikiWiki clone.
+
+    Copyright (C) 2004 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.log4j.Logger;
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.action.ViewActionBean;
+import com.ecyrd.jspwiki.parser.Heading;
+import com.ecyrd.jspwiki.parser.HeadingListener;
+import com.ecyrd.jspwiki.parser.JSPWikiMarkupParser;
+
+import java.util.*;
+import java.io.StringReader;
+import java.io.IOException;
+
+/**
+ *  Provides a table of contents.
+ *
+ *  @since 2.2
+ *  @author Janne Jalkanen
+ */
+public class TableOfContents
+    implements WikiPlugin, HeadingListener
+{
+    private static Logger log = Logger.getLogger( TableOfContents.class );
+
+    public static final String PARAM_TITLE = "title";
+    public static final String PARAM_NUMBERED = "numbered";
+    public static final String PARAM_START = "start";
+    public static final String PARAM_PREFIX = "prefix";
+
+    private static final String VAR_ALREADY_PROCESSING = "__TableOfContents.processing";
+
+    StringBuffer m_buf = new StringBuffer();
+    private boolean m_usingNumberedList = false;
+    private String m_prefix = "";
+    private int m_starting = 0;
+    private int m_level1Index = 0;
+    private int m_level2Index = 0;
+    private int m_level3Index = 0;
+    private int m_lastLevel = 0;
+
+    public void headingAdded( WikiContext context, Heading hd )
+    {
+        log.debug("HD: "+hd.m_level+", "+hd.m_titleText+", "+hd.m_titleAnchor);
+
+        switch( hd.m_level )
+        {
+          case Heading.HEADING_SMALL:
+            m_buf.append("<li class=\"toclevel-3\">");
+            m_level3Index++;
+            break;
+          case Heading.HEADING_MEDIUM:
+            m_buf.append("<li class=\"toclevel-2\">");
+            m_level2Index++;
+            break;
+          case Heading.HEADING_LARGE:
+            m_buf.append("<li class=\"toclevel-1\">");
+            m_level1Index++;
+            break;
+          default:
+            throw new InternalWikiException("Unknown depth in toc! (Please submit a bug report.)");
+        }
+
+        if (m_level1Index < m_starting)
+        {
+            // in case we never had a large heading ...
+            m_level1Index++;
+        }
+        if ((m_lastLevel == Heading.HEADING_SMALL) && (hd.m_level != Heading.HEADING_SMALL))
+        {
+            m_level3Index = 0;
+        }
+        if ( ((m_lastLevel == Heading.HEADING_SMALL) || (m_lastLevel == Heading.HEADING_MEDIUM)) &&
+                  (hd.m_level == Heading.HEADING_LARGE) )
+        {
+            m_level3Index = 0;
+            m_level2Index = 0;
+        }
+
+        String titleSection = hd.m_titleSection.replace( '%', '_' );
+        String pageName = context.getEngine().encodeName(context.getPage().getName()).replace( '%', '_' );
+
+        String url = context.getContext().getURL( ViewActionBean.class, context.getPage().getName() );
+        String sectref = "#section-"+pageName+"-"+titleSection;
+
+        m_buf.append( "<a class=\"wikipage\" href=\""+url+sectref+"\">");
+        if (m_usingNumberedList)
+        {
+            switch( hd.m_level )
+            {
+            case Heading.HEADING_SMALL:
+                m_buf.append(m_prefix + m_level1Index + "." + m_level2Index + "."+ m_level3Index +" ");
+                break;
+            case Heading.HEADING_MEDIUM:
+                m_buf.append(m_prefix + m_level1Index + "." + m_level2Index + " ");
+                break;
+            case Heading.HEADING_LARGE:
+                m_buf.append(m_prefix + m_level1Index +" ");
+                break;
+            default:
+                throw new InternalWikiException("Unknown depth in toc! (Please submit a bug report.)");
+            }
+        }
+        m_buf.append( TextUtil.replaceEntities(hd.m_titleText)+"</a></li>\n" );
+
+        m_lastLevel = hd.m_level;
+    }
+
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        WikiEngine engine = context.getEngine();
+        WikiPage   page   = context.getPage();
+        ResourceBundle rb = context.getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
+
+        if( context.getVariable( VAR_ALREADY_PROCESSING ) != null )
+            return rb.getString("tableofcontents.title");
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("<div class=\"toc\">\n");
+        sb.append("<div class=\"collapsebox\">\n");
+
+        String title = (String) params.get(PARAM_TITLE);
+        if( title != null )
+        {
+            sb.append("<h4>"+TextUtil.replaceEntities(title)+"</h4>\n");
+        }
+        else
+        {
+            sb.append("<h4>"+rb.getString("tableofcontents.title")+"</h4>\n");
+        }
+
+        // should we use an ordered list?
+        m_usingNumberedList = false;
+        if (params.containsKey(PARAM_NUMBERED))
+        {
+            String numbered = (String)params.get(PARAM_NUMBERED);
+            if (numbered.equalsIgnoreCase("true"))
+            {
+                m_usingNumberedList = true;
+            }
+            else if (numbered.equalsIgnoreCase("yes"))
+            {
+                m_usingNumberedList = true;
+            }
+        }
+
+        // if we are using a numbered list, get the rest of the parameters (if any) ...
+        if (m_usingNumberedList)
+        {
+            int start = 0;
+            String startStr = (String)params.get(PARAM_START);
+            if ((startStr != null) && (startStr.matches("^\\d+$")))
+            {
+                start = Integer.parseInt(startStr);
+            }
+            if (start < 0) start = 0;
+
+            m_starting = start;
+            m_level1Index = start - 1;
+            if (m_level1Index < 0) m_level1Index = 0;
+            m_level2Index = 0;
+            m_level3Index = 0;
+            m_prefix = (String)params.get(PARAM_PREFIX);
+            if (m_prefix == null) m_prefix = "";
+            m_lastLevel = Heading.HEADING_LARGE;
+        }
+
+        try
+        {
+            String wikiText = engine.getPureText( page );
+            boolean runFilters = 
+                "true".equals(engine.getVariableManager().getValue(context,WikiEngine.PROP_RUNFILTERS,"true"));
+            
+            try
+            {
+                if( runFilters )
+                    wikiText = engine.getFilterManager().doPreTranslateFiltering( context, wikiText );
+            }
+            catch(Exception e) 
+            {
+                log.error("Could not construct table of contents: Filter Error", e);
+                throw new PluginException("Unable to construct table of contents (see logs)");
+            }
+            
+            context.setVariable( VAR_ALREADY_PROCESSING, "x" );
+            JSPWikiMarkupParser parser = new JSPWikiMarkupParser( context,
+                                                                  new StringReader(wikiText) );
+            parser.addHeadingListener( this );
+
+            parser.parse();
+
+            sb.append( "<ul>\n"+m_buf.toString()+"</ul>\n" );
+        }
+        catch( IOException e )
+        {
+            log.error("Could not construct table of contents", e);
+            throw new PluginException("Unable to construct table of contents (see logs)");
+        }
+
+        sb.append("</div>\n</div>\n");
+
+        return sb.toString();
+    }
+
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UndefinedPagesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UndefinedPagesPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UndefinedPagesPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UndefinedPagesPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,55 @@
+/* 
+    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.plugin;
+
+import com.ecyrd.jspwiki.*;
+import java.util.*;
+
+/**
+ *  Plugin that enumerates the pages in the wiki that have not yet been defined.
+ *  Parameters: none.<BR>
+ *  From AbstractReferralPlugin:<BR>
+ *  separator: How to separate generated links; default is a wikitext line break,
+ *             producing a vertical list.<BR>
+ *  maxwidth: maximum width, in chars, of generated links.
+ *
+ *  @author Janne Jalkanen
+ */
+public class UndefinedPagesPlugin
+    extends AbstractReferralPlugin
+{
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        ReferenceManager refmgr = context.getEngine().getReferenceManager();
+        Collection links = refmgr.findUncreated();
+
+        super.initialize( context, params );
+
+        TreeSet sortedSet = new TreeSet();
+        sortedSet.addAll( links );
+        
+        filterCollection( links );
+        
+        String wikitext = wikitizeCollection( sortedSet, m_separator, ALL_ITEMS );
+        
+        return makeHTML( context, wikitext );
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UnusedPagesPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UnusedPagesPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UnusedPagesPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/UnusedPagesPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,85 @@
+/* 
+    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.plugin;
+
+import com.ecyrd.jspwiki.*;
+import java.util.*;
+
+/**
+ * Plugin for displaying pages that are not linked to in other pages.
+ * Uses the ReferenceManager.
+ * <p>
+ * Parameters: none. <BR>
+ * From AbstractReferralPlugin:<BR>
+ * separator: How to separate generated links; default is a wikitext line break,
+ *            producing a vertical list.<BR>
+ * maxwidth: maximum width, in chars, of generated links.
+ *
+ *  @author Janne Jalkanen
+ */
+public class UnusedPagesPlugin
+    extends AbstractReferralPlugin
+{
+    /**
+     *  If set to "true", attachments are excluded from display.  Value is {@value}.
+     */
+    public static final String PARAM_EXCLUDEATTS = "excludeattachments";
+
+    /**
+     *  {@inheritDoc}
+     */
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        ReferenceManager refmgr = context.getEngine().getReferenceManager();
+        Collection links = refmgr.findUnreferenced();
+        //
+        // filter out attachments if "excludeattachments" was requested:
+        //
+        String prop = (String) params.get( PARAM_EXCLUDEATTS );
+        if( TextUtil.isPositive(prop) ) 
+        {
+            //  remove links to attachments (recognizable by a slash in it)
+            //  FIXME: In 3.0, this assumption is going to fail. FIXME3.0
+            Iterator iterator = links.iterator();
+            while( iterator.hasNext() ) 
+            {
+                String link = (String) iterator.next();
+                if (link.indexOf("/")!=-1) 
+                {
+                    iterator.remove();
+                }
+            }
+        }
+
+        super.initialize( context, params );
+
+        TreeSet sortedSet = new TreeSet();
+
+        sortedSet.addAll( links );
+
+        filterCollection( links );
+        String wikitext = wikitizeCollection( sortedSet, m_separator, ALL_ITEMS );
+        
+        return makeHTML( context, wikitext );
+    }
+
+}
+

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/VotePlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/VotePlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/VotePlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/VotePlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,187 @@
+/* 
+    JSPWiki - a JSP-based WikiWiki clone.
+
+    Copyright (C) 2003 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 java.util.*;
+import java.io.*;
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.attachment.AttachmentManager;
+import com.ecyrd.jspwiki.attachment.Attachment;
+import com.ecyrd.jspwiki.providers.ProviderException;
+
+import org.apache.log4j.Logger;
+
+/**
+ *  Implements a simple voting system.  WARNING: The storage method is
+ *  still experimental; I will probably change it at some point.
+ */
+
+public class VotePlugin
+    implements WikiPlugin
+{
+    static Logger log = Logger.getLogger( VotePlugin.class );
+
+    public static final String ATTACHMENT_NAME = "VotePlugin.properties";
+
+    public static final String VAR_VOTES = "VotePlugin.votes";
+
+    /**
+     *  +1 for yes, -1 for no.
+     *
+     *  @return number of votes, or -1 if an error occurred.
+     */
+    public int vote( WikiContext context, int vote )
+    {
+        getVotes( context );
+
+        if( vote > 0 )
+        {
+            int nVotes = getYesVotes( context );
+
+            putVotes( context, "yes", ++nVotes );
+
+            return nVotes;
+        }
+        else if( vote < 0 )
+        {
+            int nVotes = getNoVotes( context );
+
+            putVotes( context, "no", ++nVotes );
+
+            return nVotes;
+        }
+
+        return -1; // Error
+    }
+
+    private void putVotes( WikiContext context, String yesno, int nVotes )
+    {
+        WikiPage   page   = context.getPage();
+
+        Properties props = getVotes( context );
+
+        props.setProperty( yesno, Integer.toString(nVotes) );
+
+        page.setAttribute( VAR_VOTES, props );
+
+        storeAttachment( context, props );
+    }
+
+    private void storeAttachment( WikiContext context, Properties props )
+    {
+        try
+        {            
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            props.store( out, "JSPWiki Votes plugin stores its votes here.  Don't modify!" );
+
+            out.close();
+
+            AttachmentManager attmgr = context.getEngine().getAttachmentManager();
+
+            Attachment att = findAttachment( context );
+
+            InputStream in = new ByteArrayInputStream( out.toByteArray() );
+
+            attmgr.storeAttachment( att, in );
+
+            in.close();
+        }
+        catch( Exception ex )
+        {
+            log.error("Unable to write properties", ex);
+        }
+    }
+
+    private Attachment findAttachment( WikiContext context )
+        throws ProviderException
+    {
+        Attachment att = context.getEngine().getAttachmentManager().getAttachmentInfo( context, ATTACHMENT_NAME );
+
+        if( att == null )
+        {
+            att = new Attachment( context.getEngine(),
+                                  context.getPage().getName(),
+                                  ATTACHMENT_NAME );
+        }
+
+        return att;
+    }
+
+    private Properties getVotes( WikiContext context )
+    {
+        WikiPage page = context.getPage();
+
+        Properties props = (Properties) page.getAttribute( VAR_VOTES );
+
+        //
+        //  Not loaded yet
+        //
+        if( props == null )
+        {
+            props = new Properties();
+
+            AttachmentManager attmgr = context.getEngine().getAttachmentManager();
+
+            try
+            {
+                Attachment att = attmgr.getAttachmentInfo( context,
+                                                           ATTACHMENT_NAME );
+
+                if( att != null )
+                {
+                    props.load( attmgr.getAttachmentStream( att ) );
+                }
+            }
+            catch( Exception e )
+            {
+                log.error( "Unable to load attachment ", e );
+            }
+        }
+
+        return props;
+    }
+
+    private int getYesVotes( WikiContext context )
+    {
+        Properties props = getVotes( context );
+
+        return TextUtil.getIntegerProperty( props, "yes", 0 );
+    }
+
+    private int getNoVotes( WikiContext context )
+    {
+        Properties props = getVotes( context );
+
+        return TextUtil.getIntegerProperty( props, "no", 0 );
+    }
+
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        String posneg = (String) params.get( "value" );
+
+        if( TextUtil.isPositive(posneg) )
+        {
+            return Integer.toString( getYesVotes( context ) );
+        }
+
+        return Integer.toString( getNoVotes( context ) );
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogArchivePlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogArchivePlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogArchivePlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogArchivePlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,200 @@
+/* 
+    JSPWiki - a JSP-based WikiWiki clone.
+
+    Copyright (C) 2003 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 com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.action.ViewActionBean;
+import com.ecyrd.jspwiki.providers.ProviderException;
+import org.apache.log4j.Logger;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ *  Creates a list of all weblog entries on a monthly basis.
+ *
+ *  @since 1.9.21
+ */
+public class WeblogArchivePlugin implements WikiPlugin
+{
+    private static Logger     log = Logger.getLogger(WeblogArchivePlugin.class);
+
+    public static final String PARAM_PAGE = "page";
+
+    private SimpleDateFormat m_monthUrlFormat;
+
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        WikiEngine engine = context.getEngine();
+
+        //
+        //  Parameters
+        //
+        String weblogName = (String) params.get( PARAM_PAGE );
+
+        if( weblogName == null ) weblogName = context.getPage().getName();
+        
+        Map<String,String> dateParams = new HashMap<String,String>();
+        dateParams.put("weblog.startDate", "'ddMMyy'");
+        dateParams.put("weblog.days", "%d");
+        m_monthUrlFormat = new SimpleDateFormat("'"+
+                                                context.getContext().getURL( ViewActionBean.class, weblogName,dateParams)+
+                                                "'");
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append( "<div class=\"weblogarchive\">\n" );
+        
+
+        //
+        //  Collect months that have blog entries
+        //
+
+        try
+        {
+            Collection months = collectMonths( engine, weblogName );
+            int year = 0;
+
+            //
+            //  Output proper HTML.
+            //
+
+            sb.append( "<ul>\n" );
+
+            if( months.size() > 0 )
+            {
+                year = ((Calendar)months.iterator().next()).get( Calendar.YEAR );
+
+                sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" );
+            }
+
+            for( Iterator i = months.iterator(); i.hasNext(); )
+            {
+                Calendar cal = (Calendar) i.next();
+
+                if( cal.get( Calendar.YEAR ) != year )
+                {
+                    year = cal.get( Calendar.YEAR );
+
+                    sb.append( "<li class=\"archiveyear\">"+year+"</li>\n" );
+                }
+
+                sb.append( "  <li>" );
+
+                sb.append( getMonthLink( cal ) );
+
+                sb.append( "</li>\n" );
+            }
+
+            sb.append( "</ul>\n" );
+            sb.append( "</div>\n" );
+        }
+        catch( ProviderException ex )
+        {
+            log.info( "Cannot get archive", ex );
+            sb.append("Cannot get archive: "+ex.getMessage());
+        }
+
+        return sb.toString();
+    }
+
+    private SortedSet collectMonths( WikiEngine engine, String page )
+        throws ProviderException
+    {
+        Comparator comp = new ArchiveComparator();
+        TreeSet res = new TreeSet( comp );
+
+        WeblogPlugin pl = new WeblogPlugin();
+
+        List blogEntries = pl.findBlogEntries( engine.getPageManager(),
+                                               page, new Date(0L), new Date() );
+        
+        for( Iterator i = blogEntries.iterator(); i.hasNext(); )
+        {
+            WikiPage p = (WikiPage) i.next();
+
+            // FIXME: Not correct, should parse page creation time.
+
+            Date d = p.getLastModified();
+            Calendar cal = Calendar.getInstance();
+            cal.setTime( d );
+            res.add( cal );
+        }
+
+        return res;
+    }
+
+    private String getMonthLink( Calendar day )
+    {
+        SimpleDateFormat monthfmt = new SimpleDateFormat( "MMMM" );
+        String result;
+
+        if( m_monthUrlFormat == null )
+        {
+            result = monthfmt.format( day.getTime() );
+        }
+        else
+        {
+            Calendar cal = (Calendar)day.clone();
+            int firstDay = cal.getActualMinimum( Calendar.DATE );
+            int lastDay  = cal.getActualMaximum( Calendar.DATE );
+
+            cal.set( Calendar.DATE, lastDay );
+            String url = m_monthUrlFormat.format( cal.getTime() );
+
+            url = TextUtil.replaceString( url, "%d", Integer.toString( lastDay-firstDay+1 ) );
+
+            result = "<a href=\""+url+"\">"+monthfmt.format(cal.getTime())+"</a>";
+        }
+
+        return result;
+
+    }
+
+    
+    /**
+     * This is a simple comparator for ordering weblog archive entries.
+     * Two dates in the same month are considered equal.
+     */
+    private static class ArchiveComparator
+        implements Comparator
+    {
+
+        public int compare( Object a, Object b ) 
+        {
+            if( a == null || b == null || 
+                !(a instanceof Calendar) || !(b instanceof Calendar) )
+            {
+                throw new ClassCastException( "Invalid calendar supplied for comparison." );
+            }
+                    
+            Calendar ca = (Calendar) a;
+            Calendar cb = (Calendar) b;
+            if( ca.get( Calendar.YEAR ) == cb.get( Calendar.YEAR ) &&
+                ca.get( Calendar.MONTH ) == cb.get( Calendar.MONTH ) )
+            {
+                return 0;
+            }
+
+            return cb.getTime().before( ca.getTime() ) ? 1 : -1;
+        }
+    }
+}

Added: incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogEntryPlugin.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogEntryPlugin.java?rev=627255&view=auto
==============================================================================
--- incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogEntryPlugin.java (added)
+++ incubator/jspwiki/branches/JSPWIKI_STRIPES_BRANCH/src/com/ecyrd/jspwiki/plugin/WeblogEntryPlugin.java Tue Feb 12 21:53:55 2008
@@ -0,0 +1,153 @@
+/* 
+    JSPWiki - a JSP-based WikiWiki clone.
+
+    Copyright (C) 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.plugin;
+
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.action.NewBlogEntryActionBean;
+import com.ecyrd.jspwiki.providers.ProviderException;
+import org.apache.log4j.Logger;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ *  Builds a simple weblog.
+ *
+ *  @since 1.9.21
+ */
+public class WeblogEntryPlugin implements WikiPlugin
+{
+    private static Logger     log = Logger.getLogger(WeblogEntryPlugin.class);
+
+    public static final int MAX_BLOG_ENTRIES = 10000; // Just a precaution.
+
+    public static final String PARAM_ENTRYTEXT = "entrytext";
+    /** 
+     * Optional parameter: page that actually contains the blog.
+     * This lets us provide a "new entry" link for a blog page 
+     * somewhere else than on the page itself.
+     */
+    // "page" for uniform naming with WeblogPlugin...
+    public static final String PARAM_BLOGNAME = "page"; 
+
+    public String getNewEntryPage( WikiEngine engine, String blogName )
+        throws ProviderException
+    {
+        SimpleDateFormat fmt = new SimpleDateFormat(WeblogPlugin.DEFAULT_DATEFORMAT);
+        String today = fmt.format( new Date() );
+            
+        int entryNum = findFreeEntry( engine.getPageManager(),
+                                      blogName,
+                                      today );
+
+                        
+        String blogPage = WeblogPlugin.makeEntryPage( blogName,
+                                                      today,
+                                                      ""+entryNum );
+
+        return blogPage;
+    }
+
+    public String execute( WikiContext context, Map params )
+        throws PluginException
+    {
+        ResourceBundle rb = context.getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
+        
+        String weblogName = (String)params.get( PARAM_BLOGNAME );
+        if( weblogName == null )
+        {
+            weblogName = context.getPage().getName();
+        }
+        WikiEngine engine = context.getEngine();
+        
+        StringBuffer sb = new StringBuffer();
+
+        String entryText = (String) params.get(PARAM_ENTRYTEXT);
+        if( entryText == null ) 
+            entryText = rb.getString("weblogentryplugin.newentry");
+        
+        Map<String,String> blogParams = new HashMap<String,String>();
+        blogParams.put("page", engine.encodeName(weblogName));
+        String url = context.getContext().getURL( NewBlogEntryActionBean.class, null, blogParams );
+            
+        sb.append("<a href=\""+url+"\">"+entryText+"</a>");
+
+        return sb.toString();
+    }
+
+    private int findFreeEntry( PageManager mgr,
+                               String baseName,
+                               String date )
+        throws ProviderException
+    {
+        Collection everyone = mgr.getAllPages();
+        int max = 0;
+
+        String startString = WeblogPlugin.makeEntryPage( baseName, date, "" );
+        
+        for( Iterator i = everyone.iterator(); i.hasNext(); )
+        {
+            WikiPage p = (WikiPage)i.next();
+
+            if( p.getName().startsWith(startString) )
+            {
+                try
+                {
+                    String probableId = p.getName().substring( startString.length() );
+
+                    int id = Integer.parseInt(probableId);
+
+                    if( id > max )
+                    {
+                        max = id;
+                    }
+                }
+                catch( NumberFormatException e )
+                {
+                    log.debug("Was not a log entry: "+p.getName() );
+                }
+            }
+        }
+
+        //
+        //  Find the first page that has no page lock.
+        //
+        int idx = max+1;
+
+        while( idx < MAX_BLOG_ENTRIES )
+        {
+            WikiPage page = new WikiPage( mgr.getEngine(),
+                                          WeblogPlugin.makeEntryPage( baseName, 
+                                                                      date, 
+                                                                      Integer.toString(idx) ) );
+            PageLock lock = mgr.getCurrentLock( page );
+
+            if( lock == null )
+            {
+                break;
+            }
+
+            idx++;
+        }
+        
+        return idx;
+    }
+    
+}