Source Code Cross Referenced for BSLTemplate.java in  » Web-Server » Brazil » sunlabs » brazil » template » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Brazil » sunlabs.brazil.template 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * BSLTemplate.java
003:         *
004:         * Brazil project web application Framework,
005:         * export version: 1.1 
006:         * Copyright (c) 1999-2001 Sun Microsystems, Inc.
007:         *
008:         * Sun Public License Notice
009:         *
010:         * The contents of this file are subject to the Sun Public License Version 
011:         * 1.0 (the "License"). You may not use this file except in compliance with 
012:         * the License. A copy of the License is included as the file "license.terms",
013:         * and also available at http://www.sun.com/
014:         * 
015:         * The Original Code is from:
016:         *    Brazil project web application Framework release 1.1.
017:         * The Initial Developer of the Original Code is: cstevens.
018:         * Portions created by cstevens are Copyright (C) Sun Microsystems, Inc.
019:         * All Rights Reserved.
020:         * 
021:         * Contributor(s): cstevens, suhler.
022:         *
023:         * Version:  1.24
024:         * Created by cstevens on 99/10/21
025:         * Last modified by suhler on 01/01/14 14:51:42
026:         */
027:
028:        package sunlabs.brazil.template;
029:
030:        import sunlabs.brazil.util.Glob;
031:        import sunlabs.brazil.util.Sort;
032:        import sunlabs.brazil.util.Format;
033:        import sunlabs.brazil.util.regexp.Regexp;
034:
035:        import java.util.Enumeration;
036:        import java.util.Properties;
037:        import java.util.StringTokenizer;
038:        import java.util.Vector;
039:        import java.io.Serializable;
040:
041:        /**
042:         * The <code>BSLTemplate</code> takes an HTML document with embedded "BSL"
043:         * markup tags in it and evaluates those special tags to produce a
044:         * standard HTML document.
045:         * <p>
046:         * BSL stands for Brazil Scripting Language.  BSL can be used to substitute
047:         * data from the request properties into the resultant document.  However,
048:         * rather than simple property substitution as is provided by the
049:         * <code>PropsTemplate</code>, this class provides the ability to iterate
050:         * over and choose amongst the values substituted with a set of simple
051:         * flow-control constructs.
052:         * <p>
053:         * BSL uses the following special tags as its language constructs: <ul>
054:         * <li> <code>&lt;foreach&gt;</code>
055:         * <li> <code>&lt;if&gt;</code>
056:         * </ul>
057:         * <p>
058:         * This template recursively evalutes the bodies/clauses of the BSL commands,
059:         * meaning that they may contain nested BSL and/or other tags defined by
060:         * other templates.
061:         * <p>
062:         * The following configuration parameter is used to initialize this
063:         * template.
064:         * <dl class=props>
065:         * <dt> debug
066:         *	<dd> If this configuration parameter is present, this class replaces
067:         *	the BSL tags with comments, so the user can keep track of where
068:         *	the dynamically generated content is coming from by examining the
069:         *	comments in the resultant HTML document.  By default, the BSL tags
070:         *	are completely eliminated from the HTML document rather than changed
071:         *	into comments.
072:         * </dl>
073:         * <hr>
074:         * <h2>&lt;foreach&gt; TAG</h2>
075:         * The <code>&lt;foreach&gt;</code> tag repeatedly evaluates its body a
076:         * selected number of times.  Each time the body is evaluated, the provided
077:         * named property is set to the next word in the provided list of words.
078:         * The body is terminated by the <code>&lt;/foreach&gt;</code> tag.
079:         * This tag is especially useful for dynamically producing lists and tables.
080:         * <ul>
081:         * <li><pre>
082:         * &lt;foreach name=<i>var</i> list="<i>value1 value2 ...</i>" [delim=x]&gt;
083:         *     &lt;property <i>var</i>&gt;
084:         * &lt;/foreach&gt;</pre>
085:         *
086:         * Iterate over the set of values "<i>value1 value2 ...</i>".  The named
087:         * property <i>var</i> is assigned each value in turn. If the optional
088:         * parameter <code>delim</code> is specified, its value  is used as
089:         * the list delimeter. By default, whitespace is used.
090:         *
091:         * <p><li><pre>
092:         * &lt;foreach name=<i>var</i> property=<i>property</i> [delim=x]&gt;
093:         *     &lt;property <i>var</i>&gt;
094:         * &lt;/foreach&gt; </pre>
095:
096:         * Iterate over the values in the other <i>property</i>.  The value
097:         * of the other property is broken up using the <code>StringTokenizer</code>
098:         * and each piece is assigned to the named property <i>var</i> in turn.
099:         * If the optional
100:         * parameter <code>delim</code> is specified, its value  is used as
101:         * the list delimeter. By default, whitespace is used.
102:         *
103:         * <p><li><pre>
104:         * &lt;foreach name=<i>var</i> property=<i>property</i> [delim=x]&gt;
105:         *     &lt;property <i>var</i>&gt;
106:         * &lt;/foreach&gt; </pre>
107:
108:         * Iterate over the values in the other <i>property</i>.  The value
109:         * of the other property is broken up using the <code>StringTokenizer</code>
110:         * and each piece is assigned to the named property <i>var</i> in turn.
111:         *
112:         * <p><li><pre>
113:         * &lt;foreach name=<i>var</i> glob=<i>pattern</i>&gt;
114:         *     &lt;property <i>var</i>.name&gt;
115:         *     &lt;property <i>var</i>.value&gt;
116:         *
117:         *     &lt;property <i>var</i>.name.1&gt;
118:         *     &lt;property <i>var</i>.name.2&gt;
119:         * &lt;/foreach&gt; </pre>
120:         *
121:         * Iterate over all the properties whose name matches the
122:         * {@link sunlabs.brazil.util.Glob glob} <i>pattern</i>.  In turn, the
123:         * following properties are set:
124:         * <br>
125:         * <code><i>var</i>.name</code> is the name of the property.
126:         * <br>
127:         * <code><i>var</i>.value</code> is the value of the property.
128:         * <br>
129:         * <code><i>var</i>.name.1</code>, <code><i>var</i>.name.2</code>, ... are
130:         * the substrings matching the wildcard characters in the pattern, if any.
131:         * 
132:         *
133:         * <p><li><pre>
134:         * &lt;foreach name=<i>var</i> glob=<i>pattern</i>&gt;
135:         *     &lt;property <i>var</i>.name&gt;
136:         *     &lt;property <i>var</i>.value&gt;
137:         *
138:         *     &lt;property <i>var</i>.name.1&gt;
139:         *     &lt;property <i>var</i>.name.2&gt;
140:         * &lt;/foreach&gt; </pre>
141:         *
142:         * Iterate over all the properties whose name matches the
143:         * {@link sunlabs.brazil.util.Glob glob} <i>pattern</i>.  In turn, the
144:         * following properties are set:
145:         * <br>
146:         * <code><i>var</i>.name</code> is the name of the property.
147:         * <br>
148:         * <code><i>var</i>.value</code> is the value of the property.
149:         * <br>
150:         * <code><i>var</i>.name.1</code>, <code><i>var</i>.name.2</code>, ... are
151:         * the substrings matching the wildcard characters in the pattern, if any.
152:         * 
153:         * <p><li><pre>
154:         * &lt;foreach name=<i>var</i> match=<i>pattern</i>&gt;
155:         *     &lt;property <i>var</i>.name&gt;
156:         *     &lt;property <i>var</i>.value&gt;
157:         *
158:         *     &lt;property <i>var</i>.name.0&gt;
159:         *     &lt;property <i>var</i>.name.1&gt;
160:         *     &lt;property <i>var</i>.name.2&gt;
161:         * &lt;/foreach&gt; </pre>
162:         *
163:         * Iterate over all the properties whose name matches the
164:         * {@link sunlabs.brazil.util.regexp.Regexp regular expression}
165:         * <i>pattern</i>.  In turn, the following properties are set:
166:         * <br>
167:         * <code><i>var</i>.name</code> is the name of the property.
168:         * <br>
169:         * <code><i>var</i>.value</code> is the value of the property.
170:         * <br>
171:         * <code><i>var</i>.name.0</code> is the substring that matched the whole
172:         * pattern.
173:         * <br>
174:         * <code><i>var</i>.name.1</code>, <code><i>var</i>.name.2</code>, ... are
175:         * the substrings matching the parenthesized subexpressions, if any.
176:         * </ul>
177:         * <h2>Sorting using <code>foreach</code></h2>
178:         * The &lt;foreach&gt; tag contains an (experimantal) feature to
179:         * change the order of iteration.  This facility is intended for
180:         * common sorting operations.  For general purpose manipulation of
181:         * the iteration order, the order should be defined either in another
182:         * handler, or by using the
183:         * {@link sunlabs.brazil.tcl.TclServerTemplate &lt;server&gt;}
184:         * directive.
185:         * <p>
186:         * The three additional parameters used to control sorting are:
187:         * <dl>
188:         * <dt> reverse
189:         * <dd> The list of items is iterated in the reverse order.
190:         *
191:         * <dt> numeric
192:         * <dd> When used in conjunction with the <code>sort</code> parameter, it
193:         *	causes the sort keys to be interpreted as numbers (or zero if the
194:         *	key is an invalid number).
195:         *
196:         * <dt> sort[=key]
197:         * <dd> The items to be iterated over are sorted.  If no key is supplied, the
198:         *	items are sorted by the property name.  If a key is supplied, its
199:         *	value is used as the sort key for the iteration.  For this to be
200:         *	meaningful, the key should contain one or more variable substitutions
201:         *	(e.g. ${...}, see * {@link sunlabs.brazil.util.Format#getProperty
202:         *	getProperty}).  Before iteration commences, the value for the key is
203:         *	computed for each item to be iterated over, by performing all of the
204:         *	'${...}' substitutions in <i>key</i> for each value, then sorting the
205:         *	items by the result.
206:         * </dl>
207:         * <hr>
208:         * <h2>&lt;if&gt; TAG</h2>
209:         * The <code>&lt;if&gt;</code> tag evaluates one of its clauses dependant upon
210:         * the value of the provided named property(ies).  The other clauses are not
211:         * evaluated and do not appear in the resultant HTML document.
212:         * The general format of the <code>&lt;if&gt;</code> tag is as follows:
213:         * <pre>
214:         * &lt;if <i>...condition...</i>&gt;
215:         *     <i>...clause...</i>
216:         * &lt;elseif <i>...condition...</i>&gt;
217:         *     <i>...clause...</i>
218:         * &lt;else&gt;
219:         *     <i>...clause...</i>
220:         * &lt;/if&gt; </pre>
221:         *
222:         * The <code>&lt;elseif&gt;</code> and <code>&lt;else&gt;</code> tags are
223:         * optional, and multiple <code>&lt;elseif&gt;</code> tags may be present.
224:         * <p>
225:         * Following are the formats of the "<i>...condition...</i>": <dl>
226:         *
227:         * <dt> <code>&lt;if <i>var</i>&gt;</code>
228:         * <dd> Test if the value of property <i>var</i> is set and is not "",
229:         *	"false", "no", "off", or the number 0.
230:         * <p>
231:         * <dt> <code>&lt;if name=<i>var</i>&gt;</code>
232:         * <dd> Same as above. <p>
233:         * <p>
234:         * <dt> <code>&lt;if name=<i>var</i> value=<i>string</i>&gt;</code>
235:         * <dd> Test if the value of property <i>var</i> is equal to the
236:         *	given <i>string</i>.
237:         * <p>
238:         * <dt> <code>&lt;if name=<i>var</i> glob=<i>pattern</i>&gt;</code>
239:         * <dd> Test if the value of property <i>var</i> matches the given
240:         *	{@link sunlabs.brazil.util.Glob glob} <i>pattern</i>.
241:         * <p>
242:         * <dt> <code>&lt;if name=<i>var</i> match=<i>pattern</i>&gt;</code>
243:         * <dd> Test if the value of property <i>var</i> matches the given
244:         *	{@link sunlabs.brazil.util.regexp.Regexp regular expression}
245:         *	<i>pattern</i>.
246:         * </dl>	
247:         * <p>
248:         * Anytime a variable name is specified, variable substitution as
249:         * described in {@link sunlabs.brazil.util.Format#getProperty} may be used.
250:         * @see <a href=/bsl.html>a sample HTML page that contains some BSL
251:         * markup</a>
252:         */
253:
254:        public class BSLTemplate extends Template implements  Serializable {
255:            private static final String DEBUG = "debug";
256:
257:            transient boolean debug;
258:
259:            /**
260:             * Called at the beginning of each HTML document that this
261:             * <code>BSLTemplate</code> is asked to process.
262:             * <p>
263:             * Checks the "debug" configuation parameter.
264:             *
265:             * @param	hr
266:             *		The request and associated HTML document that will be
267:             *		processed.
268:             *
269:             * @returns	<code>true</code> always, indicating success.
270:             */
271:            public boolean init(RewriteContext hr) {
272:                debug = (hr.request.props.getProperty(hr.prefix + DEBUG) != null);
273:                return true;
274:            }
275:
276:            private static String substProp(RewriteContext hr, String name) {
277:                return Format.subst(hr.request.props, hr.get(name));
278:            }
279:
280:            /**
281:             * Handles the "foreach" tag.
282:             */
283:            public void tag_foreach(RewriteContext hr) {
284:                String name = substProp(hr, "name");
285:                if (name == null) {
286:                    return;
287:                }
288:
289:                hr.killToken();
290:                if (debug) {
291:                    hr.append("<!-- " + hr.getBody() + " -->");
292:                }
293:
294:                String arg;
295:                boolean done = false;
296:
297:                if ((arg = substProp(hr, "list")) != null) {
298:                    done = foreach_list(hr, name, arg, substProp(hr, "delim"));
299:                } else if ((arg = substProp(hr, "glob")) != null) {
300:                    done = foreach_match(hr, name, arg, true);
301:                } else if ((arg = substProp(hr, "match")) != null) {
302:                    done = foreach_match(hr, name, arg, false);
303:                } else if ((arg = hr.get("property")) != null) {
304:                    String list = Format.getProperty(hr.request.props, arg, "");
305:                    done = foreach_list(hr, name, list, substProp(hr, "delim"));
306:                }
307:
308:                if (done == false) {
309:                    hr.accumulate(false);
310:                    skipTo(hr, "/foreach");
311:                    hr.accumulate(true);
312:                }
313:
314:                if (debug) {
315:                    hr.append("<!-- " + hr.getBody() + " -->");
316:                }
317:            }
318:
319:            private static class SortThing {
320:                String index;
321:                String s;
322:                double d;
323:
324:                public SortThing(String index, String key) {
325:                    this .index = index;
326:                    this .s = key;
327:                }
328:
329:                public SortThing(String index, double d) {
330:                    this .index = index;
331:                    this .d = d;
332:                }
333:            }
334:
335:            private static class Compare implements  Sort.Compare {
336:                boolean numeric;
337:                boolean reverse;
338:
339:                Compare(boolean numeric, boolean reverse) {
340:                    this .numeric = numeric;
341:                    this .reverse = reverse;
342:                }
343:
344:                public int compare(Object array, int index1, int index2) {
345:                    SortThing[] sa = (SortThing[]) array;
346:                    SortThing s1 = sa[index1];
347:                    SortThing s2 = sa[index2];
348:
349:                    int result = 0;
350:                    if (numeric) {
351:                        if (s1.d > s2.d) {
352:                            result = 1;
353:                        } else if (s1.d == s2.d) {
354:                            result = 0;
355:                        } else {
356:                            result = -1;
357:                        }
358:                    } else {
359:                        result = s1.s.compareTo(s2.s);
360:                    }
361:
362:                    if (reverse) {
363:                        result = -result;
364:                    }
365:                    return result;
366:                }
367:            }
368:
369:            private boolean foreach_list(RewriteContext hr, String name,
370:                    String list, String delim) {
371:                Properties props = hr.request.props;
372:
373:                Object old = props.get(name);
374:
375:                StringTokenizer st;
376:                if (delim == null) {
377:                    st = new StringTokenizer(list);
378:                } else {
379:                    st = new StringTokenizer(list, delim);
380:                }
381:                String rest = hr.lex.rest();
382:                boolean any = false;
383:
384:                String sort = hr.get("sort");
385:                boolean reverse = (substProp(hr, "reverse") != null);
386:
387:                if ((sort == null) && (reverse == false)) {
388:                    while (st.hasMoreElements()) {
389:                        props.put(name, st.nextElement());
390:                        processTo(hr, rest, "/foreach");
391:                        any = true;
392:                    }
393:                } else if ((sort == null) && (reverse == true)) {
394:                    Vector v = new Vector();
395:                    while (st.hasMoreTokens()) {
396:                        v.addElement(st.nextToken());
397:                    }
398:                    for (int i = v.size(); --i >= 0;) {
399:                        props.put(name, v.elementAt(i));
400:                        processTo(hr, rest, "/foreach");
401:                        any = true;
402:                    }
403:                } else {
404:                    boolean numeric = (substProp(hr, "numeric") != null);
405:
406:                    if (sort.length() == 0) {
407:                        sort = null;
408:                    }
409:
410:                    Vector v = new Vector();
411:                    while (st.hasMoreTokens()) {
412:                        String value = st.nextToken();
413:                        String key = value;
414:                        if (sort != null) {
415:                            props.put(name, value);
416:                            key = Format.subst(props, sort);
417:                        }
418:                        if (numeric) {
419:                            double d;
420:                            try {
421:                                d = Double.valueOf(key).doubleValue();
422:                            } catch (Exception e) {
423:                                d = 0;
424:                            }
425:                            v.addElement(new SortThing(value, d));
426:                        } else {
427:                            v.addElement(new SortThing(value, key));
428:                        }
429:                    }
430:                    SortThing[] array = new SortThing[v.size()];
431:                    v.copyInto(array);
432:
433:                    Sort.qsort(array, new Compare(numeric, reverse));
434:
435:                    for (int i = 0; i < array.length; i++) {
436:                        props.put(name, array[i].index);
437:                        processTo(hr, rest, "/foreach");
438:                        any = true;
439:                    }
440:                }
441:
442:                restore(props, name, old);
443:                return any;
444:            }
445:
446:            private static class Bag {
447:                Properties props;
448:                Regexp r;
449:                int subspecs;
450:                String pat;
451:                String nameProp;
452:                String valueProp;
453:                String[] sub;
454:                String[] subName;
455:            }
456:
457:            private boolean foreach_match(RewriteContext hr, String name,
458:                    String pat, boolean glob) {
459:                Properties props = hr.request.props;
460:
461:                Bag bag = new Bag();
462:                bag.pat = pat;
463:                bag.props = props;
464:                bag.nameProp = name + ".name";
465:                bag.valueProp = name + ".value";
466:
467:                Object oldName = props.get(bag.nameProp);
468:                Object oldValue = props.get(bag.valueProp);
469:
470:                bag.sub = new String[20];
471:                bag.subName = new String[bag.sub.length];
472:                Object[] oldSub = new Object[bag.sub.length];
473:                for (int i = 0; i < bag.sub.length; i++) {
474:                    bag.subName[i] = bag.nameProp + "." + i;
475:                    oldSub[i] = props.get(bag.subName[i]);
476:                }
477:
478:                bag.r = null;
479:                int subspecs = 0;
480:                if (glob == false) {
481:                    try {
482:                        bag.r = new Regexp(pat);
483:                    } catch (Exception e) {
484:                        bag.r = new Regexp("^$x"); // unmatchable
485:                    }
486:                    bag.subspecs = Math.min(bag.sub.length, bag.r.subspecs());
487:                }
488:
489:                Enumeration names = props.propertyNames();
490:                String rest = hr.lex.rest();
491:                boolean any = false;
492:
493:                String sort = hr.get("sort");
494:                boolean reverse = (substProp(hr, "reverse") != null);
495:
496:                if ((sort == null) && (reverse == false)) {
497:                    while (names.hasMoreElements()) {
498:                        String value = (String) names.nextElement();
499:                        if (matches(bag, true, value)) {
500:                            processTo(hr, rest, "/foreach");
501:                            any = true;
502:                        }
503:                    }
504:                } else if ((sort == null) && (reverse == true)) {
505:                    Vector v = new Vector();
506:                    while (names.hasMoreElements()) {
507:                        String value = (String) names.nextElement();
508:                        if (matches(bag, false, value)) {
509:                            v.addElement(value);
510:                        }
511:                    }
512:                    for (int i = v.size(); --i >= 0;) {
513:                        String value = (String) v.elementAt(i);
514:                        matches(bag, true, value);
515:                        processTo(hr, rest, "/foreach");
516:                        any = true;
517:                    }
518:                } else {
519:                    boolean setProps = (sort.length() > 0);
520:
521:                    Vector v = new Vector();
522:                    while (names.hasMoreElements()) {
523:                        String value = (String) names.nextElement();
524:                        if (matches(bag, setProps, value)) {
525:                            String key = value;
526:                            if (setProps) {
527:                                key = Format.subst(props, sort);
528:                            }
529:                            v.addElement(new SortThing(value, key));
530:                        }
531:                    }
532:
533:                    SortThing[] array = new SortThing[v.size()];
534:                    v.copyInto(array);
535:                    Sort.qsort(array, new Compare(false, reverse));
536:
537:                    for (int i = 0; i < array.length; i++) {
538:                        String value = array[i].index;
539:                        matches(bag, true, value);
540:                        processTo(hr, rest, "/foreach");
541:                        any = true;
542:                    }
543:                }
544:
545:                restore(props, bag.nameProp, oldName);
546:                restore(props, bag.valueProp, oldValue);
547:                for (int i = 0; i < bag.sub.length; i++) {
548:                    restore(props, bag.subName[i], oldSub[i]);
549:                }
550:
551:                return any;
552:            }
553:
554:            private boolean matches(Bag bag, boolean setProps, String name) {
555:                boolean match;
556:
557:                if (bag.r == null) {
558:                    match = Glob.match(bag.pat, name, bag.sub);
559:                    if (match && setProps) {
560:                        try {
561:                            for (int i = 0; bag.sub[i] != null; i++) {
562:                                bag.props.put(bag.subName[i + 1], bag.sub[i]);
563:                            }
564:                        } catch (Exception e) {
565:                        }
566:                    }
567:                } else {
568:                    match = bag.r.match(name, bag.sub);
569:                    if (match && setProps) {
570:                        for (int i = 0; i < bag.subspecs; i++) {
571:                            if (bag.sub[i] == null) {
572:                                bag.sub[i] = "";
573:                            }
574:                            bag.props.put(bag.subName[i], bag.sub[i]);
575:                        }
576:                    }
577:                }
578:                if (match && setProps) {
579:                    bag.props.put(bag.nameProp, name);
580:                    bag.props.put(bag.valueProp, bag.props.getProperty(name));
581:                }
582:                return match;
583:            }
584:
585:            private static void restore(Properties props, String name,
586:                    Object value) {
587:                if (value == null) {
588:                    props.remove(name);
589:                } else {
590:                    props.put(name, value);
591:                }
592:            }
593:
594:            /**
595:             * Handles the "if" tag.
596:             */
597:            public void tag_if(RewriteContext hr) {
598:                hr.killToken();
599:
600:                while (true) {
601:                    if (debug) {
602:                        hr.append("<!-- " + hr.getBody() + " -->");
603:                    }
604:                    if (isTrue(hr)) {
605:                        processClause(hr);
606:                        break;
607:                    } else {
608:                        hr.accumulate(false);
609:                        boolean elseif = false;
610:                        while (hr.nextTag()) {
611:                            String tag = hr.getTag();
612:                            if (tag.equals("if")) {
613:                                skipTo(hr, "/if");
614:                            } else if (tag.equals("/if")) {
615:                                break;
616:                            } else if (tag.equals("else")) {
617:                                hr.accumulate(true);
618:                                if (debug) {
619:                                    hr.append("<!-- " + hr.getBody() + " -->");
620:                                }
621:                                processClause(hr);
622:                                break;
623:                            } else if (tag.equals("elseif")) {
624:                                hr.accumulate(true);
625:                                elseif = true;
626:                                break;
627:                            }
628:                        }
629:                        if (elseif == false) {
630:                            break;
631:                        }
632:                    }
633:                }
634:                if (debug) {
635:                    hr.append("<!-- " + hr.getBody() + " -->");
636:                }
637:                hr.accumulate(true);
638:            }
639:
640:            private static boolean isTrue(RewriteContext hr) {
641:                String name = hr.get("name");
642:                if (name == null) {
643:                    name = hr.getArgs();
644:                }
645:                String value = Format.getProperty(hr.request.props, name, "");
646:
647:                String arg;
648:                if ((arg = substProp(hr, "value")) != null) {
649:                    return arg.equals(value);
650:                } else if ((arg = substProp(hr, "match")) != null) {
651:                    try {
652:                        return (new Regexp(arg).match(value) != null);
653:                    } catch (Exception e) {
654:                        return false;
655:                    }
656:                } else if ((arg = substProp(hr, "glob")) != null) {
657:                    return Glob.match(arg, value);
658:                } else {
659:                    /*
660:                     * Unknown or no argument specified, treat value as boolean: if
661:                     * named property exists and is not "", "false", "no", "off", or
662:                     * 0, then return true.
663:                     */
664:
665:                    if ((value.length() == 0) || value.equals("false")
666:                            || value.equals("no") || value.equals("off")) {
667:                        return false;
668:                    } else {
669:                        try {
670:                            return Integer.decode(value).intValue() != 0;
671:                        } catch (Exception e) {
672:                            return true;
673:                        }
674:                    }
675:                }
676:            }
677:
678:            private static void processClause(RewriteContext hr) {
679:                while (hr.nextTag()) {
680:                    String tag = hr.getTag();
681:                    if (tag.equals("/if")) {
682:                        break;
683:                    } else if (tag.equals("else") || tag.equals("elseif")) {
684:                        hr.accumulate(false);
685:                        skipTo(hr, "/if");
686:                        break;
687:                    } else {
688:                        hr.process();
689:                    }
690:                }
691:            }
692:
693:            private static void skipTo(RewriteContext hr, String endTag) {
694:                String startTag = endTag.substring(1);
695:                while (hr.nextTag()) {
696:                    String tag = hr.getTag();
697:                    if (tag.equals(startTag)) {
698:                        skipTo(hr, endTag);
699:                    } else if (tag.equals(endTag)) {
700:                        break;
701:                    }
702:                }
703:            }
704:
705:            private static void processTo(RewriteContext hr, String source,
706:                    String tag) {
707:                hr.lex.replace(source);
708:                while (hr.nextTag()) {
709:                    if (hr.getTag().equals(tag)) {
710:                        hr.killToken();
711:                        break;
712:                    }
713:                    hr.process();
714:                }
715:            }
716:
717:            /**
718:             * Handle the [experimental] "extract" tag.
719:             * This permits parts of a property's value to be extracted into
720:             * additional properties, based on either glob or regular expression
721:             * patterns.
722:             * <br>
723:             * &lt;extract name= prepend= glob= match=&gt;
724:             * <dl>
725:             * <dt>name   <dd>The name of the property to extract
726:             * <dt>prepend<dd>The base name for all extracted properties 
727:             *		  (defaults to "name"). If it doesn't end with a ".", 
728:             *		  one is added.
729:             * <dt>glob   <dd>The glob pattern to use for extraction.  The text
730:             *		  matching each wildcard in the pattern is extracted.
731:             * <dt>match  <dd>The regular expression pattern to use for extraction.
732:             *		  The text matching each sub-expression is extracted. If
733:             *		  "glob" is specified, then "match" is ignored.
734:             * </dl>
735:             */
736:            public void tag_extract(RewriteContext hr) {
737:                String name = hr.get("name");
738:                String prefix = substProp(hr, "prepend");
739:                String glob = substProp(hr, "glob");
740:                String match = substProp(hr, "match");
741:
742:                if (name == null) {
743:                    return;
744:                }
745:                String value = Format.getProperty(hr.request.props, name, "");
746:
747:                hr.killToken();
748:                if (debug) {
749:                    hr.append("<!-- " + hr.getBody() + " -->");
750:                }
751:
752:                if (prefix == null) {
753:                    prefix = name;
754:                }
755:                if (prefix.endsWith(".") == false) {
756:                    prefix += ".";
757:                }
758:
759:                Properties props = hr.request.props;
760:
761:                try {
762:                    if (glob != null) {
763:                        String[] sub = new String[20];
764:                        if (Glob.match(glob, value, sub)) {
765:                            for (int i = 0; sub[i] != null; i++) {
766:                                props.put(prefix + (i + 1), sub[i]);
767:                            }
768:                        }
769:                    } else if (match != null) {
770:                        Regexp r = new Regexp(match);
771:                        String[] sub = new String[r.subspecs()];
772:                        if (r.match(value, sub)) {
773:                            for (int i = 0; i < sub.length; i++) {
774:                                if (sub[i] == null) {
775:                                    sub[i] = "";
776:                                }
777:                                props.put(prefix + i, sub[i]);
778:                            }
779:                        }
780:                    }
781:                } catch (Exception e) {
782:                }
783:            }
784:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.