[pkg-java] r13111 - in branches/upstream: . jspwiki jspwiki/current jspwiki/current/src jspwiki/current/src/com jspwiki/current/src/com/ecyrd jspwiki/current/src/com/ecyrd/jspwiki jspwiki/current/src/com/ecyrd/jspwiki/plugin
Tony Mancill
tmancill at alioth.debian.org
Sat Nov 27 19:32:02 UTC 2010
Author: tmancill
Date: 2010-11-27 19:31:51 +0000 (Sat, 27 Nov 2010)
New Revision: 13111
Added:
branches/upstream/jspwiki/
branches/upstream/jspwiki/current/
branches/upstream/jspwiki/current/src/
branches/upstream/jspwiki/current/src/com/
branches/upstream/jspwiki/current/src/com/ecyrd/
branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/
branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/plugin/
branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java
Log:
[svn-inject] Installing original source of jspwiki (2.8.0)
Added: branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java
===================================================================
--- branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java (rev 0)
+++ branches/upstream/jspwiki/current/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java 2010-11-27 19:31:51 UTC (rev 13111)
@@ -0,0 +1,511 @@
+/*
+ JSPWiki - a JSP-based WikiWiki clone.
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package com.ecyrd.jspwiki.plugin;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.log4j.Logger;
+
+import com.ecyrd.jspwiki.*;
+import com.ecyrd.jspwiki.auth.AuthorizationManager;
+import com.ecyrd.jspwiki.auth.permissions.PagePermission;
+import com.ecyrd.jspwiki.parser.PluginContent;
+import com.ecyrd.jspwiki.preferences.Preferences;
+import com.ecyrd.jspwiki.preferences.Preferences.TimeFormat;
+import com.ecyrd.jspwiki.providers.ProviderException;
+
+/**
+ * <p>Builds a simple weblog.
+ * The pageformat can use the following params:</p>
+ * <p>%p - Page name</p>
+ * <p>Parameters:</p>
+ * <ul>
+ * <li><b>page</b> - which page is used to do the blog; default is the current page.</li>
+ * <li><b>entryFormat</b> - how to display the date on pages, using the J2SE SimpleDateFormat
+ * syntax. Defaults to the current locale's DateFormat.LONG format
+ * for the date, and current locale's DateFormat.SHORT for the time.
+ * Thus, for the US locale this will print dates similar to
+ * this: September 4, 2005 11:54 PM</li>
+ * <li><b>days</b> - how many days the weblog aggregator should show. If set to
+ * "all", shows all pages.</li>
+ * <li><b>pageformat</b> - What the entry pages should look like.</li>
+ * <li><b>startDate</b> - Date when to start. Format is "ddMMyy."</li>
+ * <li><b>maxEntries</b> - How many entries to show at most.</li>
+ * </ul>
+ * <p>The "days" and "startDate" can also be sent in HTTP parameters,
+ * and the names are "weblog.days" and "weblog.startDate", respectively.</p>
+ * <p>The weblog plugin also adds an attribute to each page it is on:
+ * "weblogplugin.isweblog" is set to "true". This can be used to quickly
+ * peruse pages which have weblogs.</p>
+ * @since 1.9.21
+ */
+
+// FIXME: Add "entries" param as an alternative to "days".
+// FIXME: Entries arrive in wrong order.
+
+public class WeblogPlugin
+ implements WikiPlugin, ParserStagePlugin
+{
+ private static Logger log = Logger.getLogger(WeblogPlugin.class);
+ private static final Pattern HEADINGPATTERN;
+
+ /** How many days are considered by default. Default value is {@value} */
+ private static final int DEFAULT_DAYS = 7;
+ private static final String DEFAULT_PAGEFORMAT = "%p_blogentry_";
+
+ /** The default date format used in the blog entry page names. */
+ public static final String DEFAULT_DATEFORMAT = "ddMMyy";
+
+ /** Parameter name for the startDate. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_STARTDATE = "startDate";
+ /** Parameter name for the entryFormat. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_ENTRYFORMAT = "entryFormat";
+ /** Parameter name for the days. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_DAYS = "days";
+ /** Parameter name for the allowComments. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_ALLOWCOMMENTS = "allowComments";
+ /** Parameter name for the maxEntries. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_MAXENTRIES = "maxEntries";
+ /** Parameter name for the page. Value is <tt>{@value}</tt>. */
+ public static final String PARAM_PAGE = "page";
+
+ /** The attribute which is stashed to the WikiPage attributes to check if a page
+ * is a weblog or not. You may check for its presence.
+ */
+ public static final String ATTR_ISWEBLOG = "weblogplugin.isweblog";
+
+ static
+ {
+ // This is a pretty ugly, brute-force regex. But it will do for now...
+ HEADINGPATTERN = Pattern.compile("(<h[1-4].*>)(.*)(</h[1-4]>)", Pattern.CASE_INSENSITIVE);
+ }
+
+ /**
+ * Create an entry name based on the blogname, a date, and an entry number.
+ *
+ * @param pageName Name of the blog
+ * @param date The date (in ddMMyy format)
+ * @param entryNum The entry number.
+ * @return A formatted page name.
+ */
+ public static String makeEntryPage( String pageName,
+ String date,
+ String entryNum )
+ {
+ return TextUtil.replaceString(DEFAULT_PAGEFORMAT,"%p",pageName)+date+"_"+entryNum;
+ }
+
+ /**
+ * Return just the basename for entires without date and entry numebr.
+ *
+ * @param pageName The name of the blog.
+ * @return A formatted name.
+ */
+ public static String makeEntryPage( String pageName )
+ {
+ return TextUtil.replaceString(DEFAULT_PAGEFORMAT,"%p",pageName);
+ }
+
+ /**
+ * Returns the entry page without the entry number.
+ *
+ * @param pageName Blog name.
+ * @param date The date.
+ * @return A base name for the blog entries.
+ */
+ public static String makeEntryPage( String pageName, String date )
+ {
+ return TextUtil.replaceString(DEFAULT_PAGEFORMAT,"%p",pageName)+date;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public String execute( WikiContext context, Map params )
+ throws PluginException
+ {
+ Calendar startTime;
+ Calendar stopTime;
+ int numDays = DEFAULT_DAYS;
+ WikiEngine engine = context.getEngine();
+ AuthorizationManager mgr = engine.getAuthorizationManager();
+
+ //
+ // Parse parameters.
+ //
+ String days;
+ DateFormat entryFormat;
+ String startDay = null;
+ boolean hasComments = false;
+ int maxEntries;
+ String weblogName;
+
+ if( (weblogName = (String) params.get(PARAM_PAGE)) == null )
+ {
+ weblogName = context.getPage().getName();
+ }
+
+ if( (days = context.getHttpParameter( "weblog."+PARAM_DAYS )) == null )
+ {
+ days = (String) params.get( PARAM_DAYS );
+ }
+
+ if( ( params.get(PARAM_ENTRYFORMAT)) == null )
+ {
+ entryFormat = Preferences.getDateFormat( context, TimeFormat.DATETIME );
+ }
+ else
+ {
+ entryFormat = new SimpleDateFormat( (String)params.get(PARAM_ENTRYFORMAT) );
+ }
+
+ if( days != null )
+ {
+ if( days.equalsIgnoreCase("all") )
+ {
+ numDays = Integer.MAX_VALUE;
+ }
+ else
+ {
+ numDays = TextUtil.parseIntParameter( days, DEFAULT_DAYS );
+ }
+ }
+
+
+ if( (startDay = (String)params.get(PARAM_STARTDATE)) == null )
+ {
+ startDay = context.getHttpParameter( "weblog."+PARAM_STARTDATE );
+ }
+
+ if( TextUtil.isPositive( (String)params.get(PARAM_ALLOWCOMMENTS) ) )
+ {
+ hasComments = true;
+ }
+
+ maxEntries = TextUtil.parseIntParameter( (String)params.get(PARAM_MAXENTRIES),
+ Integer.MAX_VALUE );
+
+ //
+ // Determine the date range which to include.
+ //
+
+ startTime = Calendar.getInstance();
+ stopTime = Calendar.getInstance();
+
+ if( startDay != null )
+ {
+ SimpleDateFormat fmt = new SimpleDateFormat( DEFAULT_DATEFORMAT );
+ try
+ {
+ Date d = fmt.parse( startDay );
+ startTime.setTime( d );
+ stopTime.setTime( d );
+ }
+ catch( ParseException e )
+ {
+ return "Illegal time format: "+startDay;
+ }
+ }
+
+ //
+ // Mark this to be a weblog
+ //
+
+ context.getPage().setAttribute(ATTR_ISWEBLOG, "true");
+
+ //
+ // We make a wild guess here that nobody can do millisecond
+ // accuracy here.
+ //
+ startTime.add( Calendar.DAY_OF_MONTH, -numDays );
+ startTime.set( Calendar.HOUR, 0 );
+ startTime.set( Calendar.MINUTE, 0 );
+ startTime.set( Calendar.SECOND, 0 );
+ stopTime.set( Calendar.HOUR, 23 );
+ stopTime.set( Calendar.MINUTE, 59 );
+ stopTime.set( Calendar.SECOND, 59 );
+
+ StringBuffer sb = new StringBuffer();
+
+ try
+ {
+ List<WikiPage> blogEntries = findBlogEntries( engine.getPageManager(),
+ weblogName,
+ startTime.getTime(),
+ stopTime.getTime() );
+
+ Collections.sort( blogEntries, new PageDateComparator() );
+
+ sb.append("<div class=\"weblog\">\n");
+
+ for( Iterator i = blogEntries.iterator(); i.hasNext() && maxEntries-- > 0 ; )
+ {
+ WikiPage p = (WikiPage) i.next();
+
+ if( mgr.checkPermission( context.getWikiSession(),
+ new PagePermission(p, PagePermission.VIEW_ACTION) ) )
+ {
+ addEntryHTML(context, entryFormat, hasComments, sb, p);
+ }
+ }
+
+ sb.append("</div>\n");
+ }
+ catch( ProviderException e )
+ {
+ log.error( "Could not locate blog entries", e );
+ throw new PluginException( "Could not locate blog entries: "+e.getMessage() );
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Generates HTML for an entry.
+ *
+ * @param context
+ * @param entryFormat
+ * @param hasComments True, if comments are enabled.
+ * @param buffer The buffer to which we add.
+ * @param entry
+ * @throws ProviderException
+ */
+ private void addEntryHTML(WikiContext context, DateFormat entryFormat, boolean hasComments, StringBuffer buffer, WikiPage entry)
+ throws ProviderException
+ {
+ WikiEngine engine = context.getEngine();
+ buffer.append("<div class=\"weblogentry\">\n");
+
+ //
+ // Heading
+ //
+ buffer.append("<div class=\"weblogentryheading\">\n");
+
+ Date entryDate = entry.getLastModified();
+ buffer.append( entryFormat.format(entryDate) );
+
+ buffer.append("</div>\n");
+
+ //
+ // Append the text of the latest version. Reset the
+ // context to that page.
+ //
+
+ WikiContext entryCtx = (WikiContext) context.clone();
+ entryCtx.setPage( entry );
+
+ String html = engine.getHTML( entryCtx, engine.getPage(entry.getName()) );
+
+ // Extract the first h1/h2/h3 as title, and replace with null
+ buffer.append("<div class=\"weblogentrytitle\">\n");
+ Matcher matcher = HEADINGPATTERN.matcher( html );
+ if ( matcher.find() )
+ {
+ String title = matcher.group(2);
+ html = matcher.replaceFirst("");
+ buffer.append( title );
+ }
+ else
+ {
+ buffer.append( entry.getName() );
+ }
+ buffer.append("</div>\n");
+
+ buffer.append("<div class=\"weblogentrybody\">\n");
+ buffer.append( html );
+ buffer.append("</div>\n");
+
+ //
+ // Append footer
+ //
+ buffer.append("<div class=\"weblogentryfooter\">\n");
+
+ String author = entry.getAuthor();
+
+ if( author != null )
+ {
+ if( engine.pageExists(author) )
+ {
+ author = "<a href=\""+entryCtx.getURL( WikiContext.VIEW, author )+"\">"+engine.beautifyTitle(author)+"</a>";
+ }
+ }
+ else
+ {
+ author = "AnonymousCoward";
+ }
+
+ buffer.append("By "+author+" ");
+ buffer.append( "<a href=\""+entryCtx.getURL(WikiContext.VIEW, entry.getName())+"\">Permalink</a>" );
+ String commentPageName = TextUtil.replaceString( entry.getName(),
+ "blogentry",
+ "comments" );
+
+ if( hasComments )
+ {
+ int numComments = guessNumberOfComments( engine, commentPageName );
+
+ //
+ // We add the number of comments to the URL so that
+ // the user's browsers would realize that the page
+ // has changed.
+ //
+ buffer.append( " " );
+ buffer.append( "<a target=\"_blank\" href=\""+
+ entryCtx.getURL(WikiContext.COMMENT,
+ commentPageName,
+ "nc="+numComments)+
+ "\">Comments? ("+
+ numComments+
+ ")</a>" );
+ }
+
+ buffer.append("</div>\n");
+
+ //
+ // Done, close
+ //
+ buffer.append("</div>\n");
+ }
+
+ private int guessNumberOfComments( WikiEngine engine, String commentpage )
+ throws ProviderException
+ {
+ String pagedata = engine.getPureText( commentpage, WikiProvider.LATEST_VERSION );
+
+ if( pagedata == null || pagedata.trim().length() == 0 )
+ {
+ return 0;
+ }
+
+ return TextUtil.countSections( pagedata );
+ }
+
+ /**
+ * Attempts to locate all pages that correspond to the
+ * blog entry pattern. Will only consider the days on the dates; not the hours and minutes.
+ *
+ * @param mgr A PageManager which is used to get the pages
+ * @param baseName The basename (e.g. "Main" if you want "Main_blogentry_xxxx")
+ * @param start The date which is the first to be considered
+ * @param end The end date which is the last to be considered
+ * @return a list of pages with their FIRST revisions.
+ * @throws ProviderException If something goes wrong
+ */
+ public List findBlogEntries( PageManager mgr,
+ String baseName, Date start, Date end )
+ throws ProviderException
+ {
+ Collection everyone = mgr.getAllPages();
+ ArrayList<WikiPage> result = new ArrayList<WikiPage>();
+
+ baseName = makeEntryPage( baseName );
+ SimpleDateFormat fmt = new SimpleDateFormat(DEFAULT_DATEFORMAT);
+
+ for( Iterator i = everyone.iterator(); i.hasNext(); )
+ {
+ WikiPage p = (WikiPage)i.next();
+
+ String pageName = p.getName();
+
+ if( pageName.startsWith( baseName ) )
+ {
+ //
+ // Check the creation date from the page name.
+ // We do this because RCSFileProvider is very slow at getting a
+ // specific page version.
+ //
+ try
+ {
+ //log.debug("Checking: "+pageName);
+ int firstScore = pageName.indexOf('_',baseName.length()-1 );
+ if( firstScore != -1 && firstScore+1 < pageName.length() )
+ {
+ int secondScore = pageName.indexOf('_', firstScore+1);
+
+ if( secondScore != -1 )
+ {
+ String creationDate = pageName.substring( firstScore+1, secondScore );
+
+ //log.debug(" Creation date: "+creationDate);
+
+ Date pageDay = fmt.parse( creationDate );
+
+ //
+ // Add the first version of the page into the list. This way
+ // the page modified date becomes the page creation date.
+ //
+ if( pageDay != null && pageDay.after(start) && pageDay.before(end) )
+ {
+ WikiPage firstVersion = mgr.getPageInfo( pageName, 1 );
+ result.add( firstVersion );
+ }
+ }
+ }
+ }
+ catch( Exception e )
+ {
+ log.debug("Page name :"+pageName+" was suspected as a blog entry but it isn't because of parsing errors",e);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Reverse comparison.
+ */
+ private static class PageDateComparator implements Comparator<WikiPage>
+ {
+ public int compare( WikiPage page1, WikiPage page2 )
+ {
+ if( page1 == null || page2 == null )
+ {
+ return 0;
+ }
+
+ return page2.getLastModified().compareTo( page1.getLastModified() );
+ }
+ }
+
+ /**
+ * Mark us as being a real weblog.
+ * {@inheritDoc}
+ */
+ public void executeParser(PluginContent element, WikiContext context, Map params)
+ {
+ context.getPage().setAttribute( ATTR_ISWEBLOG, "true" );
+ }
+}
More information about the pkg-java-commits
mailing list