Source Code Cross Referenced for RefCapablePropertyResourceBundle.java in  » Database-DBMS » hsql » org » hsqldb » util » 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 » Database DBMS » hsql » org.hsqldb.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2007, The HSQL Development Group
002:         * All rights reserved.
003:         *
004:         * Redistribution and use in source and binary forms, with or without
005:         * modification, are permitted provided that the following conditions are met:
006:         *
007:         * Redistributions of source code must retain the above copyright notice, this
008:         * list of conditions and the following disclaimer.
009:         *
010:         * Redistributions in binary form must reproduce the above copyright notice,
011:         * this list of conditions and the following disclaimer in the documentation
012:         * and/or other materials provided with the distribution.
013:         *
014:         * Neither the name of the HSQL Development Group nor the names of its
015:         * contributors may be used to endorse or promote products derived from this
016:         * software without specific prior written permission.
017:         *
018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021:         * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029:         */
030:
031:        package org.hsqldb.util;
032:
033:        import java.util.PropertyResourceBundle;
034:        import java.util.Map;
035:        import java.util.HashMap;
036:        import java.util.Locale;
037:        import java.util.ResourceBundle;
038:        import java.util.MissingResourceException;
039:        import java.util.Enumeration;
040:        import java.util.regex.Pattern;
041:        import java.util.regex.Matcher;
042:        import java.io.InputStream;
043:        import java.io.IOException;
044:        import java.io.UnsupportedEncodingException;
045:
046:        /**
047:         * Just like PropertyResourceBundle, except keys mapped to nothing in the
048:         * properties file will load the final String value from a text file.
049:         *
050:         * The use case is where one wants to use a ResourceBundle for Strings,
051:         * but some of the Strings are long-- too long to maintain in a Java
052:         * .properties file.
053:         * By using this class, you can put each such long String in its own
054:         * separate file, yet all keys mapped to (non-empty) values in the
055:         * .properties file will behave just like regular PropertyResourceBundle
056:         * properties.
057:         * In this documentation, I call these values read in atomically from
058:         * other files <i>referenced</i> values, because the values are not directly
059:         * in the .properties file, but are "referenced" in the .properties file
060:         * by virtue of the empty value for the key.
061:         *
062:         * You use this class in the same way as you would traditionally use
063:         * ResourceBundle:
064:         * <PRE>
065:         *  import org.hsqldb.util..RefCapablePropertyResourceBundle;
066:         *  ...
067:         *      RefCapablePropertyResourceBundle bundle =
068:         *              RefCapablePropertyResourceBundle.getBundle("subdir.xyz");
069:         *      System.out.println("Value for '1' = (" + bundle.getString("1") + ')');
070:         * </PRE>
071:         *
072:         * Just like PropertyResourceBundle, the .properties file and the
073:         * <i>referenced</i> files are read in from the classpath by a class loader,
074:         * according to the normal ResourceBundle rules.
075:         * To eliminate the need to prohibit the use of any strings in the .properties
076:         * values, and to enforce consistency, you <b>must</b> use the following rules
077:         * to when putting your referenced files into place.
078:         * <P/>
079:         * REFERENCED FILE DIRECTORY is a directory named with the base name of the
080:         * properties file, and in the same parent directory.  So, the referenced
081:         * file directory <CODE>/a/b/c/greentea</CODE> is used to hold all reference
082:         * files for properties files <CODE>/a/b/c/greentea_en_us.properties</CODE>,
083:         * <CODE>/a/b/c/greentea_de.properties</CODE>,
084:         * <CODE>/a/b/c/greentea.properties</CODE>, etc.
085:         * (BTW, according to ResourceBundle rules, this resource should be looked
086:         * up with name "a.b.c.greentea", not "/a/b/c..." or "a/b/c").
087:         * REFERENCED FILES themselves all have the base name of the property key,
088:         * with locale appendages exactly as the <i>referring</i> properties files
089:         * has, plus the suffix <CODE>.text</CODE>.
090:         * <P/>
091:         * So, if we have the following line in
092:         * <CODE>/a/b/c/greentea_de.properties</CODE>:
093:         * <PRE>
094:         *     1: eins
095:         * </PRE>
096:         * then you <b>must</b> have a reference text file
097:         * <CODE>/a/b/c/greentea/1_de.properties</CODE>:
098:         * <P/>
099:         * In reference text files,
100:         * sequences of "\r", "\n" and "\r\n" are all translated to the line
101:         * delimiter for your platform (System property <CODE>line.separator</CODE>).
102:         * If one of those sequences exists at the very end of the file, it will be
103:         * eliminated (so, if you really want getString() to end with a line delimiter,
104:         * end your file with two of them).
105:         * (The file itself is never modified-- I'm talking about the value returned
106:         * by <CODE>getString(String)</CODE>.
107:         *
108:         * To prevent throwing at runtime due to unset variables, use a wrapper class
109:         * like SqltoolRB (use SqltoolRB.java as a template).
110:         * To prevent throwing at runtime due to unset System Properties, or
111:         * insufficient parameters passed to getString(String, String[]), set the
112:         * behavior values appropriately.
113:         *
114:         * Just like all Properties files, referenced files must use ISO-8859-1
115:         * encoding, with unicode escapes for characters outside of ISO-8859-1
116:         * character set.  But, unlike Properties files, \ does not need to be
117:         * escaped for normal usage.
118:         *
119:         * The getString() methods with more than one parameter substitute for
120:         * "positional" parameters of the form "%{1}".
121:         * The getExpandedString() methods substitute for System Property names
122:         * of the form "${1}".
123:         * In both cases, you can interpose :+ and a string between the variable
124:         * name and the closing }.  This works just like the Bourne shell
125:         * ${x:+y} feature.  If "x" is set, then "y" is returned, and "y" may
126:         * contain references to the original variable without the curly braces.
127:         * In this file, I refer to the y text as the "conditional string".
128:         * One example of each type:
129:         * <PRE>
130:         *     Out val = (${condlSysProp:+Prop condlSysProp is set to $condlSysProp.})
131:         *     Out val = (%{2:+Pos Var #2 is set to %2.})
132:         * OUTPUT if neither are set:
133:         *     Out val = ()
134:         *     Out val = ()
135:         * OUTPUT if condlSysProp=alpha and condlPLvar=beta:
136:         *     Out val = (Prop condlSysProp is set to alpha.)
137:         *     Out val = (Pos Var #2 is set to beta.)
138:         * </PRE>
139:         * This feature has the following limitations.
140:         * <UL>
141:         *   <LI>The conditional string may only contain the primary variable.
142:         *   <LI>Inner instances of the primary variable may not use curly braces,
143:         *       and therefore the variable name must end at a word boundary.
144:         * </UL>
145:         * The conditional string may span newlines, and it is often very useful
146:         * to do so.
147:         *
148:         * @see java.util.PropertyResourceBundle
149:         * @see java.util.ResourceBundle
150:         * @author  blaine.simpson@admc.com
151:         */
152:        public class RefCapablePropertyResourceBundle {
153:            private PropertyResourceBundle wrappedBundle;
154:            private String baseName;
155:            private String language, country, variant;
156:            static private Map allBundles = new HashMap();
157:            public static String LS = System.getProperty("line.separator");
158:            private Pattern sysPropVarPattern = Pattern
159:                    .compile("(?s)\\Q${\\E([^}]+?)(?:\\Q:+\\E([^}]+))?\\Q}");
160:            private Pattern posPattern = Pattern
161:                    .compile("(?s)\\Q%{\\E(\\d)(?:\\Q:+\\E([^}]+))?\\Q}");
162:            private ClassLoader loader; // Needed to load referenced files
163:
164:            public static final int THROW_BEHAVIOR = 0;
165:            public static final int EMPTYSTRING_BEHAVIOR = 1;
166:            public static final int NOOP_BEHAVIOR = 2;
167:
168:            public Enumeration getKeys() {
169:                return wrappedBundle.getKeys();
170:            }
171:
172:            private RefCapablePropertyResourceBundle(String baseName,
173:                    PropertyResourceBundle wrappedBundle, ClassLoader loader) {
174:                this .baseName = baseName;
175:                this .wrappedBundle = wrappedBundle;
176:                Locale locale = wrappedBundle.getLocale();
177:                this .loader = loader;
178:                language = locale.getLanguage();
179:                country = locale.getCountry();
180:                variant = locale.getVariant();
181:                if (language.length() < 1)
182:                    language = null;
183:                if (country.length() < 1)
184:                    country = null;
185:                if (variant.length() < 1)
186:                    variant = null;
187:            }
188:
189:            /**
190:             * Same as getString(), but expands System Variables specified in
191:             * property values like ${sysvarname}.
192:             */
193:            public String getExpandedString(String key, int behavior) {
194:                String s = getString(key);
195:                Matcher matcher = sysPropVarPattern.matcher(s);
196:                int previousEnd = 0;
197:                StringBuffer sb = new StringBuffer();
198:                String varName, varValue;
199:                String condlVal; // Conditional : value
200:                while (matcher.find()) {
201:                    varName = matcher.group(1);
202:                    condlVal = ((matcher.groupCount() > 1) ? matcher.group(2)
203:                            : null);
204:                    varValue = System.getProperty(varName);
205:                    if (condlVal != null) {
206:                        // Replace varValue (the value to be substituted), with
207:                        // the post-:+ portion of the expression.
208:                        varValue = ((varValue == null) ? "" : condlVal
209:                                .replaceAll("\\Q$" + varName + "\\E\\b",
210:                                        RefCapablePropertyResourceBundle
211:                                                .literalize(varValue)));
212:                    }
213:                    if (varValue == null)
214:                        switch (behavior) {
215:                        case THROW_BEHAVIOR:
216:                            throw new RuntimeException(
217:                                    "No Sys Property set for variable '"
218:                                            + varName + "' in property value ("
219:                                            + s + ").");
220:                        case EMPTYSTRING_BEHAVIOR:
221:                            varValue = "";
222:                        case NOOP_BEHAVIOR:
223:                            break;
224:                        default:
225:                            throw new RuntimeException(
226:                                    "Undefined value for behavior: " + behavior);
227:                        }
228:                    sb
229:                            .append(s.substring(previousEnd, matcher.start())
230:                                    + ((varValue == null) ? matcher.group()
231:                                            : varValue));
232:                    previousEnd = matcher.end();
233:                }
234:                return (previousEnd < 1) ? s : (sb.toString() + s
235:                        .substring(previousEnd));
236:            }
237:
238:            /**
239:             * Replaces positional substitution patterns of the form %{\d} with
240:             * corresponding element of the given subs array.
241:             * Note that %{\d} numbers are 1-based, so we lok for subs[x-1].
242:             */
243:            public String posSubst(String s, String[] subs, int behavior) {
244:                Matcher matcher = posPattern.matcher(s);
245:                int previousEnd = 0;
246:                StringBuffer sb = new StringBuffer();
247:                String varValue;
248:                int varIndex;
249:                String condlVal; // Conditional : value
250:                while (matcher.find()) {
251:                    varIndex = Integer.parseInt(matcher.group(1)) - 1;
252:                    condlVal = ((matcher.groupCount() > 1) ? matcher.group(2)
253:                            : null);
254:                    varValue = ((varIndex < subs.length) ? subs[varIndex]
255:                            : null);
256:                    if (condlVal != null) {
257:                        // Replace varValue (the value to be substituted), with
258:                        // the post-:+ portion of the expression.
259:                        varValue = ((varValue == null) ? "" : condlVal
260:                                .replaceAll("\\Q%" + (varIndex + 1) + "\\E\\b",
261:                                        RefCapablePropertyResourceBundle
262:                                                .literalize(varValue)));
263:                    }
264:                    // System.err.println("Behavior: " + behavior);
265:                    if (varValue == null)
266:                        switch (behavior) {
267:                        case THROW_BEHAVIOR:
268:                            throw new RuntimeException(
269:                                    Integer.toString(subs.length)
270:                                            + " positional values given, but property string "
271:                                            + "contains (" + matcher.group()
272:                                            + ").");
273:                        case EMPTYSTRING_BEHAVIOR:
274:                            varValue = "";
275:                        case NOOP_BEHAVIOR:
276:                            break;
277:                        default:
278:                            throw new RuntimeException(
279:                                    "Undefined value for behavior: " + behavior);
280:                        }
281:                    sb
282:                            .append(s.substring(previousEnd, matcher.start())
283:                                    + ((varValue == null) ? matcher.group()
284:                                            : varValue));
285:                    previousEnd = matcher.end();
286:                }
287:                return (previousEnd < 1) ? s : (sb.toString() + s
288:                        .substring(previousEnd));
289:            }
290:
291:            public String getExpandedString(String key, String[] subs,
292:                    int missingPropertyBehavior, int missingPosValueBehavior) {
293:                return posSubst(
294:                        getExpandedString(key, missingPropertyBehavior), subs,
295:                        missingPosValueBehavior);
296:            }
297:
298:            public String getString(String key, String[] subs, int behavior) {
299:                return posSubst(getString(key), subs, behavior);
300:            }
301:
302:            /**
303:             * Just identifies this RefCapablePropertyResourceBundle instance.
304:             */
305:            public String toString() {
306:                return baseName + " for " + language + " / " + country + " / "
307:                        + variant;
308:            }
309:
310:            /**
311:             * Returns value defined in this RefCapablePropertyResourceBundle's
312:             * .properties file, unless that value is empty.
313:             * If the value in the .properties file is empty, then this returns
314:             * the entire contents of the referenced text file.
315:             *
316:             * @see ResourceBundle#get(String)
317:             */
318:            public String getString(String key) {
319:                String value = wrappedBundle.getString(key);
320:                if (value.length() > 0)
321:                    return value;
322:                value = getStringFromFile(key);
323:                // For conciseness and sanity, get rid of all \r's so that \n
324:                // will definitively be our line breaks.
325:                if (value.indexOf('\r') > -1)
326:                    value = value.replaceAll("\\r\\n", "\n").replaceAll("\\r",
327:                            "\n");
328:                if (value.length() > 0
329:                        && value.charAt(value.length() - 1) == '\n')
330:                    value = value.substring(0, value.length() - 1);
331:                if (!LS.equals("\n"))
332:                    value = value.replaceAll("\\n", LS);
333:                return value;
334:            }
335:
336:            /**
337:             * Use like java.util.ResourceBundle.getBundle(String).
338:             *
339:             * ClassLoader is required for our getBundles()s, since it is impossible
340:             * to get the "caller's" ClassLoader without using JNI (i.e., with pure
341:             * Java).
342:             *
343:             * @see ResourceBundle#getBundle(String)
344:             */
345:            public static RefCapablePropertyResourceBundle getBundle(
346:                    String baseName, ClassLoader loader) {
347:                return getRef(baseName, ResourceBundle.getBundle(baseName,
348:                        Locale.getDefault(), loader), loader);
349:            }
350:
351:            /**
352:             * Use exactly like java.util.ResourceBundle.get(String, Locale, ClassLoader).
353:             *
354:             * @see ResourceBundle#getBundle(String, Locale, ClassLoader)
355:             */
356:            public static RefCapablePropertyResourceBundle getBundle(
357:                    String baseName, Locale locale, ClassLoader loader) {
358:                return getRef(baseName, ResourceBundle.getBundle(baseName,
359:                        locale, loader), loader);
360:            }
361:
362:            /**
363:             * Return a ref to a new or existing RefCapablePropertyResourceBundle,
364:             * or throw a MissingResourceException.
365:             */
366:            static private RefCapablePropertyResourceBundle getRef(
367:                    String baseName, ResourceBundle rb, ClassLoader loader) {
368:                if (!(rb instanceof  PropertyResourceBundle))
369:                    throw new MissingResourceException(
370:                            "Found a Resource Bundle, but it is a "
371:                                    + rb.getClass().getName(),
372:                            PropertyResourceBundle.class.getName(), null);
373:                if (allBundles.containsKey(rb))
374:                    return (RefCapablePropertyResourceBundle) allBundles
375:                            .get(rb);
376:                RefCapablePropertyResourceBundle newPRAFP = new RefCapablePropertyResourceBundle(
377:                        baseName, (PropertyResourceBundle) rb, loader);
378:                allBundles.put(rb, newPRAFP);
379:                return newPRAFP;
380:            }
381:
382:            /**
383:             * Recursive
384:             */
385:            private InputStream getMostSpecificStream(String key, String l,
386:                    String c, String v) {
387:                String filePath = baseName.replace('.', '/') + '/' + key
388:                        + ((l == null) ? "" : ("_" + l))
389:                        + ((c == null) ? "" : ("_" + c))
390:                        + ((v == null) ? "" : ("_" + v)) + ".text";
391:                // System.err.println("Seeking " + filePath);
392:                InputStream is = loader.getResourceAsStream(filePath);
393:                // N.b.  If were using Class.getRes... instead of ClassLoader.getRes...
394:                // we would need to previx the path with "/".
395:                return (is == null && l != null) ? getMostSpecificStream(key,
396:                        ((c == null) ? null : l), ((v == null) ? null : c),
397:                        null) : is;
398:            }
399:
400:            private String getStringFromFile(String key) {
401:                byte[] ba = null;
402:                int bytesread = 0;
403:                int retval;
404:                InputStream inputStream = getMostSpecificStream(key, language,
405:                        country, variant);
406:                if (inputStream == null)
407:                    throw new MissingResourceException(
408:                            "Key '"
409:                                    + key
410:                                    + "' is present in .properties file with no value, yet "
411:                                    + "text file resource is missing",
412:                            RefCapablePropertyResourceBundle.class.getName(),
413:                            key);
414:                try {
415:                    try {
416:                        ba = new byte[inputStream.available()];
417:                    } catch (RuntimeException re) {
418:                        throw new MissingResourceException(
419:                                "Resource is too big to read in '"
420:                                        + key
421:                                        + "' value in one "
422:                                        + "gulp.\nPlease run the program with more RAM "
423:                                        + "(try Java -Xm* switches).: " + re,
424:                                RefCapablePropertyResourceBundle.class
425:                                        .getName(), key);
426:                    } catch (IOException ioe) {
427:                        throw new MissingResourceException(
428:                                "Failed to read in value for key '" + key
429:                                        + "': " + ioe,
430:                                RefCapablePropertyResourceBundle.class
431:                                        .getName(), key);
432:                    }
433:                    try {
434:                        while (bytesread < ba.length
435:                                && (retval = inputStream.read(ba, bytesread,
436:                                        ba.length - bytesread)) > 0) {
437:                            bytesread += retval;
438:                        }
439:                    } catch (IOException ioe) {
440:                        throw new MissingResourceException(
441:                                "Failed to read in value for '" + key + "': "
442:                                        + ioe,
443:                                RefCapablePropertyResourceBundle.class
444:                                        .getName(), key);
445:                    }
446:                } finally {
447:                    try {
448:                        inputStream.close();
449:                    } catch (IOException ioe) {
450:                        System.err.println("Failed to close input stream: "
451:                                + ioe);
452:                    }
453:                }
454:                if (bytesread != ba.length) {
455:                    throw new MissingResourceException(
456:                            "Didn't read all bytes.  Read in " + bytesread
457:                                    + " bytes out of " + ba.length
458:                                    + " bytes for key '" + key + "'",
459:                            RefCapablePropertyResourceBundle.class.getName(),
460:                            key);
461:                }
462:                try {
463:                    return new String(ba, "ISO-8859-1");
464:                } catch (UnsupportedEncodingException uee) {
465:                    throw new RuntimeException(uee);
466:                } catch (RuntimeException re) {
467:                    throw new MissingResourceException("Value for key '" + key
468:                            + "' too big to convert to String.  "
469:                            + "Please run the program with more RAM "
470:                            + "(try Java -Xm* switches).: " + re,
471:                            RefCapablePropertyResourceBundle.class.getName(),
472:                            key);
473:                }
474:            }
475:
476:            /**
477:             * Escape \ and $ characters in replacement strings so that nothing
478:             * funny happens.
479:             *
480:             * Once we can use Java 1.5, wipe out this method and use
481:             * java.util.regex.matcher.QuoteReplacement() instead.
482:             */
483:            public static String literalize(String s) {
484:                if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1)) {
485:                    return s;
486:                }
487:                StringBuffer sb = new StringBuffer();
488:                for (int i = 0; i < s.length(); i++) {
489:                    char c = s.charAt(i);
490:                    switch (c) {
491:                    case '\\':
492:                        sb.append('\\');
493:                        sb.append('\\');
494:                        break;
495:                    case '$':
496:                        sb.append('\\');
497:                        sb.append('$');
498:                        break;
499:                    default:
500:                        sb.append(c);
501:                        break;
502:                    }
503:                }
504:                return sb.toString();
505:            }
506:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.