/* * HighlightTemplate.java * * Brazil project web application toolkit, * export version: 2.3 * Copyright (c) 2000-2008 Sun Microsystems, Inc. * * Sun Public License Notice * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is included as the file "license.terms", * and also available at http://www.sun.com/ * * The Original Code is from: * Brazil project web application toolkit release 2.3. * The Initial Developer of the Original Code is: suhler. * Portions created by suhler are Copyright (C) Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): suhler. * * Version: 2.2 * Created by suhler on 00/10/16 * Last modified by suhler on 08/06/25 09:25:59 * * Version Histories: * * 2.2 08/06/25-09:25:59 (suhler) * don't subs \X's * * 2.1 02/10/01-16:36:50 (suhler) * version change * * 1.12 02/04/25-13:43:17 (suhler) * doc fixes * * 1.11 00/12/11-20:24:40 (suhler) * doc typo * * 1.10 00/12/11-13:30:48 (suhler) * add class=props for automatic property extraction * * 1.9 00/11/20-13:21:47 (suhler) * * 1.8 00/11/16-11:28:01 (suhler) * added edit on no-process flag * * 1.7 00/11/16-09:38:21 (suhler) * Redo for better behavior. * * 1.6 00/11/15-09:48:02 (suhler) * better diagnostics * * 1.5 00/11/06-10:48:35 (suhler) * make serializable * * 1.4 00/10/31-10:19:56 (suhler) * doc fixes * * 1.3 00/10/17-21:38:46 (suhler) * - matchcase was backwards * - don't highlight in head sections * - don't terminate filtering if no highlight set * * 1.2 00/10/17-12:20:34 (suhler) * lint * * 1.2 00/10/16-13:35:25 (Codemgr) * SunPro Code Manager data about conflicts, renames, etc... * Name history : 1 0 handlers/templates/HighlightTemplate.java * * 1.1 00/10/16-13:35:24 (suhler) * date and time created 00/10/16 13:35:24 by suhler * */ package sunlabs.brazil.template; import sunlabs.brazil.server.Server; import sunlabs.brazil.util.regexp.Regexp; import sunlabs.brazil.util.Format; import java.util.Properties; import java.io.Serializable; /** * Template class for highlighting text that matches a regular expression. * All text between html/xml entities is matched against a regular expression. * For each portion of text that matches the expression, a pair of * html/xml tags is added on either side of all matched text. * Highlighting is automatically turned off inside of head, script, style, * and server tags. *

* Properties. These are recomputed for every page that * highlight changes. *

*
highlight
A regular expression that with match any text * between entities. *
tag
the html/xml tag pair that will be added before and * after all text maching "highlight", above. The * default is "<font> ..... </font> *
options
the set of name=value options that will be added * to the starting tag of the tag pair, above. The * default is "color=red". *
matchCase
If specifies, matches are case sensitive. * The default is to ignore case when matching. *
substitute
The string to substitute for the matched text. * This is for advanced uses. If specified, the values * for tag and options are * ignored. The default is: * <${tag} ${options}>&</${tag}> * The format of the string is a regular expression * substitution string, which supports ${} style * variable substitutions from the request properties. *
mustHighlight
If not set, the entire document is surrounded * by implicit highlight tags. If set * no highlighting will take place until an actual * highlight tag is present. *
exit
If set, the template "init" method will * return false, and no further processing will * take place. This is useful if this template * is used by itself. *
*

* The following html tags are processed: *

*
highlight *
/highlight *
Only text between these tags is considered for highlighting. *
nohighlight *
/nohighlight *
Temporarily undoes the effect of a highlight tag. * In the current implementation, highlight and * nohighlight don't nest. *
* * @author Stephen Uhler * @version 2.2 HighlightTemplate.java %V% 0 */ public class HighlightTemplate extends Template implements Serializable { static final String HIGHLIGHT = "highlight"; // text to highlight static final String TAG = "tag"; // tag to surround with static final String OPTIONS = "options"; // "tag" attributes static final String MATCHCASE = "matchCase"; // set for case sens. static final String SUBSTITUTE = "substitute"; // static final String MUST = "mustHighlight"; // static final String EXIT = "exit"; // String sub; // what we substitute boolean matchCase; // true to do cases sensitive matching Regexp re = null; // regular expression to match String lastExp = ""; // cached exp string String exp; // exp string int dont; // if > 0, don't highlight boolean inHighlight; // in a highlight tag boolean inNoHighlight; // in a no highlight tag /** * This gets called at every page, at the beginning. If this is our first * time, get the config stuff out of the request properties. */ public boolean init(RewriteContext hr) { Properties props = hr.request.props; dont=0; exp = props.getProperty(hr.prefix + HIGHLIGHT, ""); if (exp.equals("")) { re = null; if (props.getProperty(hr.prefix + EXIT) != null) { return false; } } else if (!lastExp.equals(exp)) { lastExp = exp; matchCase = (props.getProperty(hr.prefix + MATCHCASE) != null); re = new Regexp(exp, !matchCase); String tag = props.getProperty(hr.prefix + TAG, "font"); String options = props.getProperty(hr.prefix + OPTIONS, "color=red"); sub = props.getProperty(hr.prefix + SUBSTITUTE); if (sub == null) { sub = "<" + tag + " " + options + ">&"; } else { sub = Format.subst(props, sub, true); } inHighlight = props.getProperty(hr.prefix + MUST) == null; hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, "Setting: (" + sub + ") for: " + exp); } return true; } /** * Gets all text between tags - highlighting it appropriately. * To restrict the tag set, define the entities and set the shouldHighlight * flag appropriately. */ public void string(RewriteContext hr) { String body = hr.getToken(); // System.out.println("Re " + inHighlight + inNoHighlight + dont + re); if (inHighlight && !inNoHighlight && dont==0 && re != null && re.match(body) != null) { hr.append(re.subAll(body, sub)); } } /** * Don't do highlight inside the following sections */ public void tag_head(RewriteContext hr) { push(); } public void tag_slash_head(RewriteContext hr) { pop(); } public void tag_script(RewriteContext hr) { push(); } public void tag_slash_script(RewriteContext hr) { pop(); } public void tag_style(RewriteContext hr) { push(); } public void tag_slash_style(RewriteContext hr) { pop(); } public void tag_server(RewriteContext hr) { push(); } public void tag_slash_server(RewriteContext hr) { pop(); } void push() { dont++; } void pop() { if (dont > 0) { dont--; } } /** * The special entities highlight and * nohighlight * may be used to turn highlighting on or off in certain areas. */ public void tag_highlight(RewriteContext hr) { inHighlight=true; } public void tag_slash_highlight(RewriteContext hr) { inHighlight=false; } public void tag_nohighlight(RewriteContext hr) { inNoHighlight=true; } public void tag_slash_nohighlight(RewriteContext hr) { inNoHighlight=false; } }