001: /*
002: * regain - A file search engine providing plenty of formats
003: * Copyright (C) 2004 Til Schneider
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: Til Schneider, info@murfman.de
020: *
021: * CVS information:
022: * $RCSfile$
023: * $Source$
024: * $Date: 2005-08-10 16:00:46 +0200 (Mi, 10 Aug 2005) $
025: * $Author: til132 $
026: * $Revision: 155 $
027: */
028: package net.sf.regain.util.sharedtag;
029:
030: import java.util.HashMap;
031: import java.util.Locale;
032:
033: import net.sf.regain.RegainException;
034: import net.sf.regain.util.io.Localizer;
035: import net.sf.regain.util.io.MultiLocalizer;
036:
037: /**
038: * A tag that may be used within the taglib technology or the simpleweb
039: * technology.
040: *
041: * @author Til Schneider, www.murfman.de
042: */
043: public abstract class SharedTag {
044:
045: /** Specifies that the tag body should be evaluated. */
046: public static final int EVAL_TAG_BODY = 1;
047:
048: /** Specifies that the tag body should be skipped. */
049: public static final int SKIP_TAG_BODY = 2;
050:
051: /** The MultiLocalizer that holds the Localizers for the tags. */
052: private static MultiLocalizer mMultiLocalizer;
053:
054: /** The parameters for this tag. May be null. */
055: private HashMap mParamMap;
056:
057: /**
058: * The current Localizer. Is <code>null</code> when the is currently not
059: * executed.
060: */
061: private Localizer mLocalizer;
062:
063: /**
064: * Creates a new instance of SharedTag.
065: */
066: public SharedTag() {
067: }
068:
069: /**
070: * Gets the name of this Tag.
071: * <p>
072: * The name of the tag is extracted from the class name. In order to work,
073: * subclasses must be named using the pattern [TagName]Tag
074: * (e.g. <code>NavigationTag</code> for the tag <code>navigation</code>).
075: *
076: * @return The name of this tag.
077: */
078: public String getTagName() {
079: String className = getClass().getName();
080:
081: // Remove the package name
082: int packageEnd = className.lastIndexOf('.');
083:
084: // Remove the Tag postfix
085: int nameEnd = className.length();
086: if (className.endsWith("Tag")) {
087: nameEnd -= 3;
088: }
089: // NOTE: This even works, if packageEnd is -1
090: String tagName = className.substring(packageEnd + 1, nameEnd)
091: .toLowerCase();
092:
093: int packageStart;
094: while ((packageStart = className.lastIndexOf('.',
095: packageEnd - 1)) != -1) {
096: String packageName = className.substring(packageStart + 1,
097: packageEnd);
098: if (packageName.equals("sharedlib")) {
099: break;
100: } else {
101: tagName = packageName + "_" + tagName;
102: packageEnd = packageStart;
103: }
104: }
105:
106: return tagName;
107: }
108:
109: /**
110: * Sets a parameter.
111: *
112: * @param name The parameter's name.
113: * @param value The parameter's value.
114: */
115: public void setParameter(String name, String value) {
116: if (mParamMap == null) {
117: mParamMap = new HashMap();
118: }
119:
120: mParamMap.put(name, value);
121: }
122:
123: /**
124: * Gets a parameter.
125: *
126: * @param name The parameter's name.
127: * @return The value of the parameter or <code>null</code> if the parameter
128: * was not set.
129: */
130: public String getParameter(String name) {
131: if (mParamMap == null) {
132: return null;
133: } else {
134: String value = (String) mParamMap.get(name);
135: if (value != null) {
136: value = localize(value);
137: }
138: return value;
139: }
140: }
141:
142: /**
143: * Gets a parameter.
144: *
145: * @param name The parameter's name.
146: * @param defaultValue The value to return if the parameter was not set.
147: * @return The value of the parameter or the default value if the parameter
148: * was not set.
149: */
150: public String getParameter(String name, String defaultValue) {
151: String asString = getParameter(name);
152: if (asString == null) {
153: return defaultValue;
154: } else {
155: return asString;
156: }
157: }
158:
159: /**
160: * Gets a parameter.
161: *
162: * @param name The parameter's name.
163: * @param mandatory Specifies whether the parameter is mandatory.
164: * @return The parameter value or <code>null</code> if no such parameter was
165: * given and mandatory is <code>false</code>.
166: * @throws RegainException If mandatory is <code>true</code> and the parameter
167: * was not specified.
168: */
169: public String getParameter(String name, boolean mandatory)
170: throws RegainException {
171: String asString = getParameter(name);
172: if (mandatory && (asString == null)) {
173: throw new RegainException("Parameter " + name + " of tag "
174: + getTagName() + " was not specified");
175: } else {
176: return asString;
177: }
178: }
179:
180: /**
181: * Gets a parameter and converts it to an int.
182: *
183: * @param name The name of the parameter.
184: * @param defaultValue The value to return if the parameter is not set.
185: * @throws RegainException When the parameter value is not a number.
186: * @return The int value of the parameter.
187: */
188: public int getParameterAsInt(String name, int defaultValue)
189: throws RegainException {
190: String asString = getParameter(name);
191: if (asString == null) {
192: return defaultValue;
193: } else {
194: try {
195: return Integer.parseInt(asString);
196: } catch (NumberFormatException exc) {
197: throw new RegainException("Parameter " + name
198: + " of tag " + getTagName()
199: + " must be a number: '" + asString + "'");
200: }
201: }
202: }
203:
204: /**
205: * Gets a parameter and converts it to a boolean.
206: *
207: * @param name The name of the parameter.
208: * @param defaultValue The value to return if the parameter is not set.
209: * @throws RegainException When the parameter value is not a number.
210: * @return The int value of the parameter.
211: */
212: public boolean getParameterAsBoolean(String name,
213: boolean defaultValue) throws RegainException {
214: String asString = getParameter(name);
215: if (asString == null) {
216: return defaultValue;
217: } else {
218: if (asString.equalsIgnoreCase("true")) {
219: return true;
220: } else if (asString.equalsIgnoreCase("false")) {
221: return false;
222: } else {
223: throw new RegainException("Parameter " + name
224: + " of tag " + getTagName()
225: + " must be a boolean: '" + asString + "'");
226: }
227: }
228: }
229:
230: /**
231: * Sets the tag execution context.
232: * <p>
233: * Is called by the shared tag engine before the start tag is processed.
234: *
235: * @param request The request to get the context from
236: * @throws RegainException If setting the context failed.
237: */
238: public final void setContext(PageRequest request)
239: throws RegainException {
240: // Get the Localizer
241: mLocalizer = (Localizer) request
242: .getContextAttribute("Localizer");
243: if (mLocalizer == null) {
244: // The default resource bundles are in english
245: Locale.setDefault(Locale.ENGLISH);
246:
247: // Get the locale
248: Locale locale = request.getLocale();
249: if (locale == null) {
250: locale = Locale.getDefault();
251: }
252:
253: // Init the MultiLocalizer if nessesary
254: if (mMultiLocalizer == null) {
255: mMultiLocalizer = new MultiLocalizer(request
256: .getResourceBaseUrl(), "msg");
257: }
258:
259: // Get the localizer
260: mLocalizer = mMultiLocalizer.getLocalizer(locale);
261: request.setContextAttribute("Localizer", mLocalizer);
262: }
263: }
264:
265: /**
266: * Unsets the tag execution context.
267: * <p>
268: * Is called by the shared tag engine after the end tag was processed.
269: */
270: public final void unsetContext() {
271: mLocalizer = null;
272: }
273:
274: /**
275: * Gets the localizer.
276: * <p>
277: * Note: The localizer is only not null, when the tag is currently executed.
278: * Which is in the {@link #printStartTag(PageRequest, PageResponse)}, the
279: * {@link #printAfterBody(PageRequest, PageResponse)} ant the
280: * {@link #printEndTag(PageRequest, PageResponse)}.
281: *
282: * @return The localizer.
283: */
284: protected Localizer getLocalizer() {
285: return mLocalizer;
286: }
287:
288: /**
289: * Localizes a text. Replaces all "{msg:...}" fields with the matching
290: * localized messages.
291: *
292: * @param text The text to localize.
293: * @return The localized text.
294: */
295: private String localize(String text) {
296: StringBuffer buffer = null;
297: int startPos = 0;
298: int endPos = 0;
299: while ((startPos = text.indexOf("{msg:", endPos)) != -1) {
300: if (buffer == null) {
301: buffer = new StringBuffer(text.length());
302: }
303:
304: // Add the text before
305: buffer.append(text.substring(endPos, startPos));
306:
307: // Get the new endPos
308: endPos = text.indexOf('}', startPos + 1);
309: if (endPos == -1) {
310: endPos = text.length();
311: }
312:
313: // Append the localized message
314: String key = text.substring(startPos + 5, endPos);
315: buffer.append(mLocalizer.msg(key, "?"));
316: }
317:
318: if (buffer != null) {
319: // Append the last text
320: buffer.append(text.substring(endPos + 1));
321:
322: text = buffer.toString();
323: }
324:
325: return text;
326: }
327:
328: /**
329: * Called when the parser reaches the start tag.
330: *
331: * @param request The page request.
332: * @param response The page response.
333: * @return {@link #EVAL_TAG_BODY} if you want the tag body to be evaluated or
334: * {@link #SKIP_TAG_BODY} if you want the tag body to be skipped.
335: * @throws RegainException If there was an exception.
336: */
337: public int printStartTag(PageRequest request, PageResponse response)
338: throws RegainException {
339: return EVAL_TAG_BODY;
340: }
341:
342: /**
343: * Called after the body content was evaluated.
344: *
345: * @param request The page request.
346: * @param response The page response.
347: * @return {@link #EVAL_TAG_BODY} if you want the tag body to be evaluated
348: * once again or {@link #SKIP_TAG_BODY} if you want to print the
349: * end tag.
350: * @throws RegainException If there was an exception.
351: */
352: public int printAfterBody(PageRequest request, PageResponse response)
353: throws RegainException {
354: return SKIP_TAG_BODY;
355: }
356:
357: /**
358: * Called when the parser reaches the end tag.
359: *
360: * @param request The page request.
361: * @param response The page response.
362: * @throws RegainException If there was an exception.
363: */
364: public void printEndTag(PageRequest request, PageResponse response)
365: throws RegainException {
366: }
367:
368: /**
369: * Gets the String representation of this tag.
370: *
371: * @return The String representation.
372: */
373: public String toString() {
374: return getTagName();
375: }
376:
377: }
|