KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > guiframework > util > Util


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.tools.guiframework.util;
25
26 import com.iplanet.jato.RequestContext;
27 import com.iplanet.jato.RequestManager;
28 import com.iplanet.jato.view.DisplayField;
29 import com.iplanet.jato.view.View;
30 import com.iplanet.jato.view.ViewBean;
31 import com.iplanet.jato.view.ContainerView;
32
33 import com.sun.enterprise.tools.guiframework.exception.FrameworkException;
34 import com.sun.enterprise.tools.guiframework.view.DescriptorViewManager;
35 import com.sun.enterprise.tools.guiframework.view.descriptors.ViewDescriptor;
36
37 import java.util.ArrayList JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.List JavaDoc;
41 import java.util.Map JavaDoc;
42 import java.util.Stack JavaDoc;
43
44
45 public class Util {
46     
47     /**
48      * <P>This method can be used to substitute Request attributes into a
49      * String, or return the value of the attribute if the substitution is the
50      * whole String. This method looks for the LAST occurance of startToken
51      * in the given String. It then searches from that location (if found) to
52      * the first occurance of endToken. The value inbetween is used as the
53      * name of the Request attribute to retrieve. The value of the Request
54      * attribute (w/ a toString()) is substituted into the string beginning
55      * where the startToken was found and ending at the endToken (replacing
56      * the start and end tokens too of course). This process is repeated
57      * until no more occurances of startToken are found within the String.</P>
58      *
59      * <P>This algorithm will accomodate nested variables (e.g. "$(A($x))").
60      * It also allows that attribute itself to contain variables. Care should
61      * be taken to ensure that the attribute included does not directly or
62      * indirectly refer to itself -- this will cause an infinite loop.</P>
63      *
64      * <P>There is one special case where the string to be evaluated begins
65      * with the startToken and ends with the endToken. In this case, string
66      * substitution is NOT performed. Instead the value of the request
67      * attribute is returned. The request attribute value is not examined or
68      * processed any further in this case.</P>
69      *
70      * <P>NOTE: This method has been enhanced to substitute other types as
71      * well. The syntax is now $attribute(..) or $session(...), etc. More
72      * documentation to come later...</P>
73      *
74      *
75      * @param ctx The RequestContext
76      * @param vd The closest ViewDescriptor to this string
77      * @param string The string to be evaluated.
78      * @param startToken Marks the beginning "$"
79      * @param typeDelim Marks separation of type/variable "("
80      * @param endToken Marks the end of the variable ")"
81      *
82      * @return The new string with substitutions, or the specified request
83      * attribute value.
84      */

85     public static Object JavaDoc replaceVariableWithAttribute(RequestContext ctx,
86             ViewDescriptor vd, String JavaDoc string, String JavaDoc startToken,
87             String JavaDoc typeDelim, String JavaDoc endToken) {
88
89     int stringLen = string.length();
90     int delimIndex;
91     int endIndex, matchingIndex;
92     int parenSemi;
93     int startTokenLen = startToken.length();
94     int delimLen = typeDelim.length();
95     int endTokenLen = endToken.length();
96     boolean expressionIsWholeString = false;
97     char firstEndChar = SUB_END.charAt(0);
98     char firstDelimChar = SUB_TYPE_DELIM.charAt(0);
99     char currChar;
100     String JavaDoc type;
101     Object JavaDoc variable;
102
103     for (int startIndex = string.lastIndexOf(startToken); startIndex != -1;
104          startIndex = string.lastIndexOf(startToken, startIndex-1)) {
105
106         // Find first typeDelim
107
delimIndex = string.indexOf(typeDelim, startIndex+startTokenLen);
108         if (delimIndex == -1) {
109         continue;
110         }
111
112         // Next find the end token
113
parenSemi = 0;
114         endIndex = -1;
115         // Iterate through the string looking for the matching end
116
for (int curr = delimIndex+delimLen; curr<stringLen; ) {
117         // Get the next char...
118
currChar = string.charAt(curr);
119         if ((currChar == firstDelimChar) && typeDelim.equals(string.substring(curr, curr+delimLen))) {
120             // Found the start of another... inc the semi
121
parenSemi++;
122             curr += delimLen;
123             continue;
124         }
125         if ((currChar == firstEndChar) && endToken.equals(string.substring(curr, curr+endTokenLen))) {
126             parenSemi--;
127             if (parenSemi < 0) {
128             // Found the right one!
129
endIndex = curr;
130             break;
131             }
132             // Found one, but this isn't the right one
133
curr += endTokenLen;
134             continue;
135         }
136         curr++;
137         }
138         if (endIndex == -1) {
139         // We didn't find a matching end...
140
continue;
141         }
142
143 /*
144         // Next find end token
145         endIndex = string.indexOf(endToken, delimIndex+delimLen);
146         matchingIndex = string.lastIndexOf(typeDelim, endIndex);
147         while ((endIndex != -1) && (matchingIndex != delimIndex)) {
148         // We found a endToken, but not the matching one...keep looking
149         endIndex = string.indexOf(endToken, endIndex+endTokenLen);
150         matchingIndex = string.lastIndexOf(typeDelim, matchingIndex-delimLen);
151         }
152         if ((endIndex == -1) || (matchingIndex == -1)) {
153         continue;
154         }
155 */

156
157         // Handle special case where string starts with startToken and ends
158
// with endToken (and no replacements inbetween). This is special
159
// because we don't want to convert the attribute to a string, we
160
// want to return it (this allows Object types).
161
if ((startIndex == 0) && (endIndex == string.lastIndexOf(endToken)) && (string.endsWith(endToken))) {
162         // This is the special case...
163
expressionIsWholeString = true;
164         }
165
166         // Pull off the type...
167
type = string.substring(startIndex+startTokenLen, delimIndex);
168         DataSource ds = (DataSource)_dataSourceMap.get(type);
169         if (ds == null) {
170         throw new FrameworkException("Invalid type '"+type+
171             "' in attribute value: '"+string+"'.");
172         }
173
174         // Pull off the variable...
175
variable = string.substring(delimIndex+delimLen, endIndex);
176
177         // Get the value...
178
variable = ds.getValue(ctx, vd, (String JavaDoc)variable);
179         if (expressionIsWholeString) {
180         return variable;
181         }
182
183         // Make new string
184
string = string.substring(0, startIndex) + // Before replacement
185
((variable == null) ? "" : variable.toString()) +
186              string.substring(endIndex+endTokenLen); // After
187
stringLen = string.length();
188     }
189
190     // Return the string
191
return string;
192     }
193
194
195     /**
196      * This method replaces the $(..) variables with their attribute values.
197      * It will only do this for Strings and List's that contain Strings.
198      */

199     public static Object JavaDoc replaceVariablesWithAttributes(Object JavaDoc value, ViewDescriptor vd) {
200     if (value == null) {
201         return null;
202     }
203     return replaceVariablesWithAttributes(
204         RequestManager.getRequestContext(), vd, value);
205     }
206
207
208     /**
209      * This method replaces the $(..) variables with their attribute values.
210      * It will only do this for Strings and List's that contain Strings.
211      */

212     public static Object JavaDoc replaceVariablesWithAttributes(RequestContext ctx, ViewDescriptor vd, Object JavaDoc value) {
213     if (value == null) {
214         return null;
215     }
216     if (value instanceof String JavaDoc) {
217         value = Util.replaceVariableWithAttribute(
218         ctx,
219         vd,
220         (String JavaDoc)value,
221         SUB_START,
222         SUB_TYPE_DELIM,
223         SUB_END);
224     } else if (value instanceof List JavaDoc) {
225         // Create a new List b/c invalid to change shared List
226
List JavaDoc list = ((List JavaDoc)value);
227         int size = list.size();
228         List JavaDoc newList = new ArrayList JavaDoc(size);
229         Iterator JavaDoc it = list.iterator();
230         while (it.hasNext()) {
231         newList.add(replaceVariablesWithAttributes(ctx, vd, it.next()));
232         }
233         return newList;
234     }
235     return value;
236     }
237
238
239     /**
240      * This method returns true of the given String is non-null and has a
241      * length greater than 0.
242      *
243      * @param str The String to check
244      *
245      * @return true if non-null String with length greater than 0
246      */

247     public static boolean hasValue(String JavaDoc str) {
248         if (str == null) {
249             return false;
250     }
251         return str.length() > 0;
252     }
253
254     
255     public static String JavaDoc replace(String JavaDoc src, String JavaDoc toReplace, String JavaDoc replaceWith) {
256         String JavaDoc str = src;
257         while (true) {
258             int startIndex = str.indexOf(toReplace);
259             if (startIndex < 0)
260                 break;
261             int length = str.length();
262             int endIndex = startIndex + toReplace.length();
263             str = str.substring(0, startIndex) + replaceWith + str.substring(endIndex, length);
264         }
265         return str;
266     }
267
268
269     /**
270      * This is a helper method to get a View's "Top-level" ViewBean.
271      *
272      * @param view The View which needs to find its ViewBean.
273      */

274     public static ViewBean getParentViewBean(View view) {
275     while (view != null) {
276         if (view instanceof ViewBean) {
277             // Make sure that this "ViewBean" is the top ViewBean
278
if (view.getParent() == null) {
279             return (ViewBean)view;
280         }
281         }
282         view = view.getParent();
283     }
284     return null;
285     }
286
287
288     /**
289      * <P> This interface defines a String substitution data source. This
290      * is used to retrieve values when a $&lt;type&gt;(&lt;data&gt;) is
291      * encountered within a parameter value.</P>
292      *
293      * <P> Implementations of this interface may register themselves
294      * statically to extend the capabilities of the $() substitution
295      * mechanism.</P>
296      */

297     public interface DataSource {
298     Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key);
299     }
300
301
302     /**
303      * <P> This DataSource provides access to HttpRequest attributes. It
304      * uses the data portion of the substitution String as a key to the
305      * HttpRequest attribute Map.</P>
306      */

307     public static class AttributeDataSource implements DataSource {
308     public AttributeDataSource() {
309     }
310
311     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
312         return ctx.getRequest().getAttribute(key);
313     }
314     }
315
316
317     /**
318      * <P> This DataSource provides access to PageSession attributes. It
319      * uses the data portion of the substitution String as a key to the
320      * PageSession attribute Map.</P>
321      */

322     public static class PageSessionDataSource implements DataSource {
323     public PageSessionDataSource() {
324     }
325
326     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
327         while (vd.getParent() != null) {
328         vd = vd.getParent();
329         }
330         return ((ViewBean)vd.getView(ctx)).getPageSessionAttribute(key);
331     }
332     }
333     
334     /**
335      * <P> This DataSource provides access to HttpRequest Parameters. It
336      * uses the data portion of the substitution String as a key to the
337      * HttpRequest Parameter Map.</P>
338      */

339     public static class RequestParameterDataSource implements DataSource {
340     public RequestParameterDataSource() {
341     }
342
343     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
344             return ctx.getRequest().getParameter(key);
345         }
346     }
347
348
349     /**
350      * <P> This DataSource provides access to View XML parameters. It
351      * uses the data portion of the substitution String as a key to the
352      * ViewDescriptor's parameter Map. Until a value is found, it will
353      * continue to look at the parent's ViewDescriptor parameter Map.
354      * If no parameter matching the name is found, then null is
355      * returned.</P>
356      */

357     public static class ParameterDataSource implements DataSource {
358     public ParameterDataSource() {
359     }
360
361     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
362         Object JavaDoc value = null;
363         for (; (value == null) && (vd != null); vd = vd.getParent()) {
364         value = vd.getParameter(key);
365         }
366         return value;
367     }
368     }
369
370
371     /**
372      * <P> This DataSource simply returns the key that it is given. This is
373      * useful for supplying $()'s around the string you wish to mark as a
374      * string. If not used, characters such as '=' will be interpretted
375      * as a separator causing your string to be split -- which can be
376      * very undesirable. Mostly useful in "if" statements.</P>
377      */

378     public static class EscapeDataSource implements DataSource {
379     public EscapeDataSource() {
380     }
381
382     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
383         return key;
384     }
385     }
386
387
388     /**
389      * <P> This DataSource provides access to HttpSession attributes. It
390      * uses the data portion of the substitution String as a key to the
391      * HttpSession Map.</P>
392      */

393     public static class SessionDataSource implements DataSource {
394     public SessionDataSource() {
395     }
396
397     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
398         return ctx.getRequest().getSession().getAttribute(key);
399     }
400     }
401
402
403     /**
404      * <P> This DataSource provides access to DisplayField values. It
405      * uses the data portion of the substitution String as the
406      * DisplayField name to find. This is a non-qualified DisplayField
407      * name. It will walk up the View tree starting at the View object * cooresponding to the ViewDescriptor which contained this
408      * expression. At each ContainerView, it will look for a child with
409      * a matching name.</P>
410      */

411     public static class DisplayFieldDataSource implements DataSource {
412     public DisplayFieldDataSource() {
413     }
414
415     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
416             while (vd != null) {
417                 View view = vd.getView(ctx);
418                 if (view instanceof ContainerView) {
419                     DisplayField child = null;
420                     try {
421                         child = (DisplayField) ((ContainerView) view).getChild(key);
422                     } catch (Exception JavaDoc ex) {
423             // Ignore, we will continue to look for the value
424
}
425                     if (child != null) {
426                         return child.getValue();
427                     }
428                 }
429                 vd = vd.getParent();
430             }
431             return null;
432     }
433     }
434
435     /**
436      * <P> This class provides an implementation for the syntax $this(xyz)
437      * where xyz can be any of the following.</P>
438      *
439      * <UL><LI>View -- Returns the current View</LI>
440      * <LI>ViewDescriptor -- Returns the current ViewDescriptor</LI>
441      * <LI>ParentViewDescriptor -- The parent ViewDescriptor</LI>
442      * <LI>TopViewDescriptor -- The "top" ViewDescriptor</LI>
443      * <LI>ParentView -- Returns the parent View (may be null)</LI>
444      * <LI>ViewBean -- Returns the ViewBean</LI>
445      * <LI>ViewBeanName -- Returns the ViewBean name</LI>
446      * <LI>DefaultModel -- Returns the DefaultModel of the closest
447      * ContainerView</LI></UL>
448      */

449     public static class ThisDataSource implements DataSource {
450     public ThisDataSource() {
451     }
452
453     public Object JavaDoc getValue(RequestContext ctx, ViewDescriptor vd, String JavaDoc key) {
454         Object JavaDoc value = null;
455
456         if ((key.equalsIgnoreCase(THIS_VIEW)) || (key.length() == 0)) {
457         value = vd.getView(ctx);
458         } else if (key.equalsIgnoreCase(THIS_VIEW_DESCRIPTOR)) {
459         value = vd;
460         } else if (key.equalsIgnoreCase(THIS_PARENT_VIEW_DESCRIPTOR)) {
461         value = vd.getParent();
462         } else if (key.equalsIgnoreCase(THIS_TOP_VIEW_DESCRIPTOR)) {
463         while (vd.getParent() != null) {
464             vd = vd.getParent();
465         }
466                 value = vd;
467         } else if (key.equalsIgnoreCase(THIS_PARENT_VIEW)) {
468         vd = vd.getParent();
469         value = (vd == null) ? null : vd.getView(ctx);
470         } else if (key.equalsIgnoreCase(THIS_VIEWBEAN)) {
471             // Get the top ViewDescriptor (may not be a ViewBean)
472
while (vd.getParent() != null) {
473             vd = vd.getParent();
474         }
475
476         // Get corresponding View
477
value = vd.getView(ctx);
478
479         // Make sure its the top View (ViewBean)
480
while (((View)value).getParent() != null) {
481             value = ((View)value).getParent();
482         }
483         } else if (key.equalsIgnoreCase(THIS_VIEW_BEAN_NAME)) {
484         while (vd.getParent() != null) {
485             vd = vd.getParent();
486         }
487                 value=vd.getName();
488                 
489                 /*commenting out because this could cause infinte loop in beforeCreate */
490                 /*
491         // Get corresponding View
492         value = vd.getView(ctx);
493
494         // Make sure its the top View (ViewBean)
495         while (((View)value).getParent() != null) {
496             value = ((View)value).getParent();
497         }
498                 value = ((View)value).getName();
499                  */

500         } else if (key.equalsIgnoreCase(THIS_DEFAULT_MODEL)) {
501         // This will not work in a beforeCreate! (infinite loop)
502
View view = vd.getView(ctx);
503         while ((view != null) && !(view instanceof ContainerView)) {
504             view = view.getParent();
505         }
506         value = ((ContainerView)view).getDefaultModel();
507         } else {
508         throw new FrameworkException("'"+key+"' is not valid in $this("
509             +key+"). This was found on '"+vd.getName()+"'.");
510         }
511     
512         return value;
513     }
514
515     /**
516      * <P> Defines "view" in $this(view). Returns the View object.</P>
517      */

518     public static final String JavaDoc THIS_VIEW = "View";
519
520
521     /**
522      * <P> Defines "ParentView" in $this(ParentView). Returns the
523      * parent View object.</P>
524      */

525     public static final String JavaDoc THIS_PARENT_VIEW = "ParentView";
526
527
528     /**
529      * <P> Defines "ViewBean" in $this(ViewBean). Returns the ViewBean
530      * object.</P>
531      */

532     public static final String JavaDoc THIS_VIEWBEAN = "ViewBean";
533
534
535     /**
536      * <P> Defines "ViewDescriptor" in $this(ViewDescriptor). Returns
537      * the ViewDescriptor.</P>
538      */

539     public static final String JavaDoc THIS_VIEW_DESCRIPTOR = "ViewDescriptor";
540
541
542     /**
543      * <P> Defines "ParentViewDescriptor" in $this(ParentViewDescriptor).
544      * Returns the parent ViewDescriptor object.</P>
545      */

546     public static final String JavaDoc THIS_PARENT_VIEW_DESCRIPTOR= "ParentViewDescriptor";
547
548
549     /**
550      * <P> Defines "TopViewDescriptor" in $this(TopViewDescriptor).
551      * Returns the top ViewDescriptor object -- most likely a
552      * ViewBean ViewDescriptor.</P>
553      */

554     public static final String JavaDoc THIS_TOP_VIEW_DESCRIPTOR= "TopViewDescriptor";
555
556
557     /**
558      * <P> Defines "ViewBeanName" in $this(ViewBeanName). Returns the
559      * ViewBeanName.</P>
560      */

561     public static final String JavaDoc THIS_VIEW_BEAN_NAME = "ViewBeanName";
562
563
564     /**
565      * <P> Defines "DefaultModel" in $this(DefaultModel). Returns the
566      * DefaultModel associated with the nearest ContainerView.</P>
567      */

568     public static final String JavaDoc THIS_DEFAULT_MODEL = "DefaultModel";
569     }
570
571     public static void main(String JavaDoc args[]) {
572     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape(ViewDescriptor))", "$", "(", ")"));
573     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape(EEPersistenceManager))", "$", "(", ")"));
574
575     System.out.println(""+replaceVariableWithAttribute(null, null, "$es$cape$escape(EEPersistenceManager))", "$", "(", ")"));
576     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escapeEEP$ersistenceManager))", "$", "(", ")"));
577
578     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape(EEPersistenceManager)))", "$", "(", ")"));
579     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape(EEPersistenceManager())", "$", "(", ")"));
580     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape($escape(EEPersistenceManager()))==$escape(EEPersistenceManager()))", "$", "(", ")"));
581     System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape($escape(EEPersistenceManager()))==$escape(EEPersistenceManager()))", "$", "(", ")"));
582     for (int x=0; x<100000; x++) {
583         System.out.println(""+replaceVariableWithAttribute(null, null, "$escape($escape(EEPers"+x+"istenceManager()))==$escape(EEPersistenceManager())", "$", "(", ")"));
584     }
585     }
586
587     /**
588      * Contains the data sources for $type(variable) syntax.
589      */

590     public static Map JavaDoc _dataSourceMap = new HashMap JavaDoc();
591
592
593     /**
594      * <P> Defines "attribute" in $attribute(...). This allows you to
595      * retrieve an HttpRequest attribute.</P>
596      */

597     public static final String JavaDoc ATTRIBUTE = "attribute";
598
599
600     /**
601      * <P> Defines "pageSession" in $pageSession(...). This allows you to
602      * retrieve a PageSession attribute.</P>
603      */

604     public static final String JavaDoc PAGE_SESSION = "pageSession";
605
606
607     /**
608      * <P> Defines "parameter" in $parameter(...). This allows you to
609      * retrieve a parameter from the view XML file.</P>
610      */

611     public static final String JavaDoc PARAMETER = "parameter";
612
613
614     /**
615      * <P> Defines "session" in $session(...). This allows you to retrieve
616      * an HttpSession attribute.
617      */

618     public static final String JavaDoc SESSION = "session";
619
620
621     /**
622      * <P> Defines "requestParameter" in $requestParameter(...). This allows
623      * you to retrieve a HttpRequest parameter (QUERY_STRING
624      * parameter).</P>
625      */

626     public static final String JavaDoc REQUEST_PARAMETER = "requestParameter";
627
628
629     /**
630      * <P> Defines "display" in $display(...). This allows you to retrive
631      * a DisplayField value.</P>
632      */

633     public static final String JavaDoc DISPLAY = "display";
634
635
636     /**
637      * <P> Defines "this" in $this(...). This allows you to retrieve a
638      * number of different objects related to the relative placement of
639      * this expression.</P>
640      *
641      * @see ThisDataSource
642      */

643     public static final String JavaDoc THIS = "this";
644
645
646     /**
647      * <P> Defines "escape" in $escape(...). This allows some reserved
648      * characters to be escaped in "if" attributes. Such as '=' or
649      * '|'.</P>
650      */

651     public static final String JavaDoc ESCAPE = "escape";
652
653
654     static {
655     AttributeDataSource attrDS = new AttributeDataSource();
656     _dataSourceMap.put(ATTRIBUTE, attrDS);
657     _dataSourceMap.put("", attrDS);
658     _dataSourceMap.put(PAGE_SESSION, new PageSessionDataSource());
659     _dataSourceMap.put(PARAMETER, new ParameterDataSource());
660     _dataSourceMap.put(SESSION, new SessionDataSource());
661     _dataSourceMap.put(REQUEST_PARAMETER, new RequestParameterDataSource());
662     _dataSourceMap.put(DISPLAY, new DisplayFieldDataSource());
663     _dataSourceMap.put(THIS, new ThisDataSource());
664     _dataSourceMap.put(ESCAPE, new EscapeDataSource());
665     }
666
667
668     /**
669      * The '$' character marks the beginning of a substituion in a String.
670      */

671     public static final String JavaDoc SUB_START = "$";
672
673
674     /**
675      * The '(' character marks the beginning of the data content of a String
676      * substitution.
677      */

678     public static final String JavaDoc SUB_TYPE_DELIM = "(";
679
680
681     /**
682      * The ')' character marks the end of the data content for a String
683      * substitution.
684      */

685     public static final String JavaDoc SUB_END = ")";
686 }
687
Popular Tags