001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.rendering.plugins;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.roller.RollerException;
023: import org.apache.roller.pojos.WeblogEntryData;
024: import org.apache.roller.pojos.WebsiteData;
025:
026: import java.io.UnsupportedEncodingException;
027: import java.net.URLEncoder;
028: import java.text.FieldPosition;
029: import java.text.MessageFormat;
030: import java.util.Map;
031: import java.util.regex.Matcher;
032: import java.util.regex.Pattern;
033:
034: /**
035: * Implements the common portion of search link plugins.
036: *
037: * @author <a href="mailto:anil@busybuddha.org">Anil Gangolli</a>
038: * @version 2.1
039: */
040: public abstract class SearchPluginBase {
041: private String baseVersion = "2.1";
042: private Log mLogger;
043:
044: /**
045: * Instantiation is per request.
046: */
047: public SearchPluginBase() {
048: mLogger = getLogger();
049: }
050:
051: /**
052: * Initialize. Called once for each request.
053: *
054: * @see org.apache.roller.model.PagePlugin#init(WebsiteData, Object, String baseUrl, org.apache.velocity.context.Context)
055: */
056: public void init(WebsiteData website) throws RollerException {
057: if (mLogger.isDebugEnabled()) {
058: mLogger.debug(getClass().getName() + "; version: "
059: + getVersion() + "; base version " + baseVersion);
060: }
061: }
062:
063: /**
064: * Apply plugin to content of specified String.
065: *
066: * @param str String to which plugin should be applied.
067: * @return Results of applying plugin to string.
068: * @see org.apache.roller.model.PagePlugin#render(String)
069: */
070: public String render(WeblogEntryData entry, String str) {
071: Pattern pattern = getPattern();
072: Matcher m = pattern.matcher(str);
073: StringBuffer result = new StringBuffer(str.length() + 128); // rough guess at a reasonable length
074: Object[] args = new Object[] { "", "", null, null };
075: while (m.find()) {
076: // parse out the parts of the match
077: String type = m.group(1);
078: boolean feelinLucky = type.equals("!"); // are ya feelin lucky? are ya punk?
079: String linkText = m.group(2);
080: String searchText = m.group(3);
081: if (searchText == null || searchText.length() == 0) {
082: searchText = linkText;
083: }
084:
085: // URL-encode the search text
086: String encodedSearchText = encodeSearchText(searchText);
087:
088: // form the replacement string
089: MessageFormat linkFormat = feelinLucky ? getLuckyLinkFormat()
090: : getLinkFormat();
091: StringBuffer replacement = new StringBuffer(128);
092: args[2] = linkText;
093: args[3] = encodedSearchText;
094: linkFormat.format(args, replacement, new FieldPosition(0));
095:
096: // append replacement
097: m.appendReplacement(result, replacement.toString());
098: }
099: m.appendTail(result);
100:
101: return result.toString();
102: }
103:
104: /**
105: * Returns the human-friendly name of this Plugin. This is what users will see.
106: *
107: * @return The human-friendly name of this Plugin.
108: * @see org.apache.roller.model.PagePlugin#getName()
109: */
110: public abstract String getName();
111:
112: /**
113: * Briefly describes the function of the Plugin. May contain HTML.
114: *
115: * @return A brief description of the Plugin.
116: * @see org.apache.roller.model.PagePlugin#getDescription()
117: */
118: public abstract String getDescription();
119:
120: /**
121: * Return the logger for this class.
122: *
123: * @return the logger for this class.
124: */
125: protected abstract Log getLogger();
126:
127: /**
128: * Return the implementation version.
129: *
130: * @return the implementation version.
131: */
132: protected abstract String getVersion();
133:
134: /**
135: * Get the regexp pattern for finding search links in the input text. Three matching groups are expected: (1) The
136: * lucky or not indicator (either <code>!</code> or <code>:</code>) (2) the link text (3) the search text (optional,
137: * defaults to the link text).
138: *
139: * @return the regexp pattern for finding search links in the input text
140: */
141: protected abstract Pattern getPattern();
142:
143: /**
144: * The MessageFormat for the replacement string (actual HTML link) that will form the replacement in the regular
145: * (non-"lucky") case. This must have two positional parameters "{2} and {3}" which are the link text and
146: * (URL-encoded) search text from the regexp pattern. Note that the parameters "{0}" and "{1}" are not used. They
147: * will be empty strings.
148: *
149: * @return the message format for non-"lucky" search links.
150: */
151: protected abstract MessageFormat getLinkFormat();
152:
153: /**
154: * The MessageFormat for the replacement string (actual HTML link) that will form the replacement in the "lucky"
155: * case. This must have two positional parameters "{2} and {3}" which are the link text and (URL-encoded) search
156: * text from the regexp pattern. Note that the parameters "{0}" and "{1}" are not used. They will be empty
157: * strings.
158: *
159: * @return the message format for "lucky" search links.
160: */
161: protected abstract MessageFormat getLuckyLinkFormat();
162:
163: // Private helper to URL encode the search text.
164: private String encodeSearchText(String searchText) {
165: // URL encode the searchtext
166: try {
167: return URLEncoder.encode(searchText, "UTF-8");
168: } catch (UnsupportedEncodingException uex) {
169: // By Java spec, this should never actually occur for UTF-8. If it does, we barf bitterly.
170: throw new RuntimeException(uex);
171: }
172: }
173:
174: }
|