📄 topictagplugin.java
字号:
/* * Copyright (c) 2004 * Anil R. Gangolli. All rights reserved. * * Distributed with Roller Weblogger under the terms of the Roller license. */package org.roller.presentation.velocity.plugins.topictag;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.velocity.context.Context;import org.roller.RollerException;import org.roller.config.RollerConfig;import org.roller.model.BookmarkManager;import org.roller.model.RollerFactory;import org.roller.pojos.BookmarkData;import org.roller.pojos.WeblogEntryData;import org.roller.pojos.WebsiteData;import org.roller.presentation.RollerRequest;import org.roller.presentation.velocity.PagePlugin;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.text.FieldPosition;import java.text.MessageFormat;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;import java.util.regex.PatternSyntaxException;/** * Provides an easy way to write topic tag links for Technorati (or similar services). * <p/> * Looks for occurrences of topic tag specifiers of the form * <pre> * <code>topic:{topicbookmark}[tag]</code> OR <code>topic:[tag]</code> * </pre> * and replaces them with a topic tag link of the form: * <pre> * <code><a rel="tag" href="site/tag">tag</a></code> * </pre> * <p/> * More information on topic tag links can be found at <a href="http://www.technorati.com">Technorati</a>. * <p/> * <p/> * In the first form, the <code>topicbookmark</code> is used as the name of a bookmark, and the URL from that bookmark * entry is used as the <code>site</code> portion in the <code>href</code> of the link. * <p/> * All folders are searched to find a bookmark with the name specified by <code>topicbookmark</code>. A name must match * exactly, ignoring case. The first matching bookmark is used, and folders may be searched in any order. The * bookmark's URL value can end in a "/" or not; either will work. * <p/> * The second form is equivalent to using the string "Default Topic Site" as the value of <code>topicbookmark</code>. * <p/> * If the bookmark lookup fails, then "http://www.technorati.com/tag" is used as the site name in the topic tag link. * <p/> * You can specify some Roller site-wide properties in the roller.properties or roller-custom.properties to override * some of the defaults of this plugin. All of these are optional. * <p/> * <dl> <dt><code>org.roller.presentation.velocity.plugins.topictag.TopicTagPlugin.defaultTopicBookmarkName</code></dt> * <dd>Specify the name of the default topic bookmark instead of "Default Topic Site"</dd> * <p/> * <dt><code>org.roller.presentation.velocity.plugins.topictag.TopicTagPlugin.defaultTopicSite</code></dt> <dd>Specify * the default site name to be used instead of "http://www.technorati.com" for the case in which all of the lookups * fail.</dd> * <p/> * <dt><code>org.roller.presentation.velocity.plugins.topictag.TopicTagPlugin.tagPatternWithBookmark</code></dt> <dd>Can * be used to redefine the regular expression used to find a long-form topic tag specifiers in the input. This pattern * corresponds to the "long form" and must have two matching groups. Group 1 must correspond to the bookmark name. * Group 2 must correspond to the tag.</dd> * <p/> * <dt><code>org.roller.presentation.velocity.plugins.topictag.TopicTagPlugin.tagPatternDefaultBookmark</code></dt> * <dd>Can be used to redefine the regular expression used to find short-form topic tag specifiers in the input. This * pattern must have one matching group, which corresponds to the tag.</dd> * <p/> * <dt><code>org.roller.presentation.velocity.plugins.topictag.TopicTagPlugin.linkFormatString</code></dt> <dd>Can be * used to redefine the format of the generated link. This string is a message format string with three positional * parameters. Parameter <code>{0}</code> represents the site including a trailing "/", parameter <code>{1}</code> * represents the url-encoded tag and parameter <code>{2}</code> represents the original unencoded tag text.</dd> * <p/> * </dl> * * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a> * @version 0.3 */public class TopicTagPlugin implements PagePlugin{ private static final String version = "0.3"; private static final Log mLogger = LogFactory.getFactory().getInstance(TopicTagPlugin.class); // Default values of properties that can be set from the web.xml configuration. private String defaultTopicBookmarkName = "Default Topic Site"; private String defaultTopicSite = "http://www.technorati.com/tag"; private String tagRegexWithBookmark = "topic:\\{(.*?)\\}\\[(.*?)\\]"; private String tagRegexWithoutBookmark = "topic:\\[(.*?)\\]"; private String linkFormatString = "<a rel=\"tag\" href=\"{0}{1}\">{2}</a>"; // Compiled form of the regular expressions above. Compiled during the init() private Pattern tagPatternWithBookmark; private Pattern tagPatternWithoutBookmark; private MessageFormat linkFormat; // A map of the user's bookmarks (values of type BookmarkData) keyed by name (String). If the user has multiple // bookmarks with the same name in different folders, only one gets used (the last encountered). private Map userBookmarks; public TopicTagPlugin() { } /** * Initialize the plugin instance. This sets up the configurable properties and default topic site. * * @param rreq Plugins may need to access RollerRequest. * @param ctx Plugins may place objects into the Velocity Context. * @see PagePlugin#init(org.roller.presentation.RollerRequest, org.apache.velocity.context.Context) */ public void init(RollerRequest rreq, Context ctx) throws RollerException { if (mLogger.isDebugEnabled()) { mLogger.debug("TopicTagPlugin v. " + version); } // Initialize property settings initializeProperties(); // Build map of the user's bookmarks userBookmarks = buildBookmarkMap(rreq.getWebsite()); // Determine default topic site from bookmark if present BookmarkData defaultTopicBookmark = (BookmarkData) userBookmarks.get(defaultTopicBookmarkName); if (defaultTopicBookmark != null) defaultTopicSite = defaultTopicBookmark.getUrl(); // Append / to defaultTopicSite if it doesn't have it if (!defaultTopicSite.endsWith("/")) { defaultTopicSite += "/"; } // Compile patterns and make sure they have the correct number of matching groups in them. try { tagPatternWithBookmark = Pattern.compile(tagRegexWithBookmark); } catch (PatternSyntaxException e) { throw new RollerException("Invalid regular expression for topic tags with bookmark '" + tagRegexWithBookmark + "': " + e.getMessage()); } int groupCount = tagPatternWithBookmark.matcher("").groupCount(); if (groupCount != 2) { throw new RollerException("Regular expression for topic tags with bookmark '" + tagRegexWithBookmark + "' contains wrong number of capture groups. Must have exactly 2. Contains " + groupCount); } try { tagPatternWithoutBookmark = Pattern.compile(tagRegexWithoutBookmark); } catch (PatternSyntaxException e) { throw new RollerException("Invalid regular expression for topic tags without bookmark '" + tagRegexWithoutBookmark + "': " + e.getMessage()); } groupCount = tagPatternWithoutBookmark.matcher("").groupCount(); if (groupCount != 1) { throw new RollerException("Regular expression for topic tags without bookmark '" + tagRegexWithoutBookmark + "' contains wrong number of capture groups. Must have exactly 1. Contains " + groupCount); } // Create link format from format string setLinkFormat(new MessageFormat(linkFormatString)); } /** * Apply the plugin to the given entry. Returns the entry text with topic tags expanded. * * @param entry WeblogEntry to which plugin should be applied. * @param skipFlagIgnored the "skip flag" is ignored for this plugin * @return Results of applying plugin to entry. */ public String render(WeblogEntryData entry, boolean skipFlagIgnored) { String entryText = entry.getText(); StringBuffer result = new StringBuffer(entryText.length()); MessageFormat fmt = getLinkFormat(); // Replace all of the instances matching the pattern with bookmark specified. Matcher m = tagPatternWithBookmark.matcher(entryText); while (m.find()) { String bookmark = m.group(1); String tag = m.group(2); String site = getBookmarkSite(bookmark); if (site == null) { site = getDefaultTopicSite(); } if (!site.endsWith("/")) { site += "/"; } String link = generateLink(fmt, site, tag); m.appendReplacement(result, link); } m.appendTail(result); // Now, in a second phase replace all of the instances matching the pattern without bookmark specified. entryText = result.toString(); result = new StringBuffer(entryText.length()); m = tagPatternWithoutBookmark.matcher(entryText); while (m.find()) { String tag = m.group(1); String site = getDefaultTopicSite(); String link = generateLink(fmt, site, tag); m.appendReplacement(result, link); } m.appendTail(result); return result.toString();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -