/*
NamespaceIndexPlugin
-- Dirk Frederickx, Jul 2005
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 brushed.jspwiki.namespaceplugin;
import com.ecyrd.jspwiki.*;
import com.ecyrd.jspwiki.plugin.*;
import com.ecyrd.jspwiki.providers.ProviderException;
import org.apache.log4j.Logger;
import org.apache.oro.text.*;
import org.apache.oro.text.regex.*;
import java.io.StringWriter;
import java.util.*;
/**
* Builds an index of all pages.
*
Parameters
*
* - itemsPerLine: How many items should be allowed per line before break.
* If set to zero (the default), will not write breaks.
*
- namespace: page prefix used as namespace
*
- include: Include only these pages.
*
- exclude: Exclude with this pattern.
*
*
* @author Alain Ravet
* @author Janne Jalkanen
* @since 1.9.9
*/
public class NamespaceIndexPlugin implements WikiPlugin
{
protected static Logger log = Logger.getLogger(NamespaceIndexPlugin.class);
public static final String INITIALS_COLOR = "red" ;
private static final int DEFAULT_ITEMS_PER_LINE = 0 ;
private static final String PARAM_NAMESPACE = "namespace"; //added
private static final String PARAM_ITEMS_PER_LINE = "itemsPerLine";
private static final String PARAM_INCLUDE = "include";
private static final String PARAM_EXCLUDE = "exclude";
private String m_namespace = null; //added
private int m_currentNofPagesOnLine = 0;
private int m_itemsPerLine;
protected String m_previousPageFirstLetter = "";
protected StringWriter m_bodyPart = new StringWriter();
protected StringWriter m_headerPart = new StringWriter();
private Pattern m_includePattern;
private Pattern m_excludePattern;
public String execute( WikiContext i_context , Map i_params )
throws PluginException
{
//
// Parse arguments and create patterns.
//
// NamespaceIndexPlugin stuff added
m_namespace = (String) i_params.get(PARAM_NAMESPACE);
if( m_namespace == null ) m_namespace = "";
PatternCompiler compiler = new GlobCompiler();
m_itemsPerLine = TextUtil.parseIntParameter( (String) i_params.get(PARAM_ITEMS_PER_LINE),
DEFAULT_ITEMS_PER_LINE );
try
{
String ptrn = (String) i_params.get(PARAM_INCLUDE);
if( ptrn == null ) ptrn = m_namespace + "*"; //added
m_includePattern = compiler.compile(ptrn);
ptrn = (String) i_params.get(PARAM_EXCLUDE);
if( ptrn == null ) ptrn = "";
m_excludePattern = compiler.compile(ptrn);
}
catch( MalformedPatternException e )
{
throw new PluginException("Illegal pattern detected."); // FIXME, make a proper error.
}
//
// Get pages, then sort.
//
final Collection allPages = getAllPagesSortedByName( i_context );
final TranslatorReader linkProcessor = new TranslatorReader( i_context,
new java.io.StringReader ( "" ) );
//
// Build the page.
//
buildIndexPageHeaderAndBody( i_context, allPages, linkProcessor );
StringBuffer res = new StringBuffer();
res.append( "\n" );
res.append( "\n" );
res.append( "
\n" );
res.append( m_bodyPart.toString() );
res.append( "
\n
\n" );
return res.toString();
}
private void buildIndexPageHeaderAndBody( WikiContext context,
final Collection i_allPages ,
final TranslatorReader i_linkProcessor )
{
PatternMatcher matcher = new Perl5Matcher();
for( Iterator i = i_allPages.iterator (); i.hasNext ();)
{
WikiPage curPage = (WikiPage) i.next();
if( matcher.matches( curPage.getName(), m_includePattern ) )
{
if( !matcher.matches( curPage.getName(), m_excludePattern ) )
{
++m_currentNofPagesOnLine;
// shorten the pageName -- for NamespaceIndexPlugin
String pageName = curPage.getName();
if( pageName.startsWith(m_namespace) && ( !pageName.equals(m_namespace)) )
{
pageName = pageName.substring( m_namespace.length() );
}
pageName = TextUtil.beautifyString( pageName );
//pageName = TextUtil.beautifyString( pageName, " " ); //to be compiled to v2.2.x
String pageNameFirstLetter = pageName.substring(0,1).toUpperCase();
boolean sameFirstLetterAsPreviousPage = m_previousPageFirstLetter.equals(pageNameFirstLetter);
if( !sameFirstLetterAsPreviousPage )
{
addLetterToIndexHeader( pageNameFirstLetter );
addLetterHeaderWithLine( pageNameFirstLetter );
m_currentNofPagesOnLine = 1;
m_previousPageFirstLetter = pageNameFirstLetter;
}
addPageToIndex( context, curPage, i_linkProcessor, pageName );
breakLineIfTooLong();
}
}
} // for
}
/**
* Gets all pages, then sorts them.
*/
static Collection getAllPagesSortedByName( WikiContext i_context )
{
final WikiEngine engine = i_context.getEngine();
final PageManager pageManager = engine.getPageManager();
if( pageManager == null )
return null;
Collection result = new TreeSet( new Comparator() {
public int compare( Object o1, Object o2 )
{
if( o1 == null || o2 == null ) { return 0; }
WikiPage page1 = (WikiPage)o1,
page2 = (WikiPage)o2;
return page1.getName().compareTo( page2.getName() );
}
});
try
{
Collection allPages = pageManager.getAllPages();
result.addAll( allPages );
}
catch( ProviderException e )
{
log.fatal("PageProvider is unable to list pages: ", e);
}
return result;
}
private void addLetterToIndexHeader( final String i_firstLetter )
{
final boolean noLetterYetInTheIndex = ! "".equals(m_previousPageFirstLetter);
if( noLetterYetInTheIndex )
{
m_headerPart.write(" - " );
}
m_headerPart.write("" + i_firstLetter + "" );
}
private void addLetterHeaderWithLine( final String i_firstLetter )
{
m_bodyPart.write("\n
" +
""+
""+
i_firstLetter+"" +
"
\n" );
}
/* added i_text argument -- NamespaceIndexPlugin */
protected void addPageToIndex( WikiContext context, WikiPage i_curPage, final TranslatorReader i_linkProcessor, final String i_text )
{
final boolean notFirstPageOnLine = 2 <= m_currentNofPagesOnLine;
if( notFirstPageOnLine )
{
m_bodyPart.write(", ");
}
m_bodyPart.write( i_linkProcessor.makeLink( TranslatorReader.READ,
i_curPage.getName(),
i_text ) );
// context.getEngine().beautifyTitleNoBreak(i_curPage.getName()) )
}
protected void breakLineIfTooLong()
{
final boolean limitReached = (m_itemsPerLine == m_currentNofPagesOnLine);
if( limitReached )
{
m_bodyPart.write( "
\n" );
m_currentNofPagesOnLine = 0;
}
}
}