Source Code Cross Referenced for StringUtils.java in  » Net » openfire » org » jivesoftware » 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 » Net » openfire » org.jivesoftware.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * $Revision: 6032 $
0003:         * $Date: 2006-11-09 17:16:09 -0800 (Thu, 09 Nov 2006) $
0004:         *
0005:         * Copyright (C) 2004-2006 Jive Software. All rights reserved.
0006:         *
0007:         * This software is published under the terms of the GNU Public License (GPL),
0008:         * a copy of which is included in this distribution.
0009:         */package org.jivesoftware.util;
0010:
0011:        import java.io.UnsupportedEncodingException;
0012:        import java.security.MessageDigest;
0013:        import java.security.NoSuchAlgorithmException;
0014:        import java.text.BreakIterator;
0015:        import java.util.*;
0016:        import java.util.concurrent.ConcurrentHashMap;
0017:
0018:        /**
0019:         * Utility class to peform common String manipulation algorithms.
0020:         */
0021:        public class StringUtils {
0022:
0023:            // Constants used by escapeHTMLTags
0024:            private static final char[] QUOTE_ENCODE = """.toCharArray();
0025:            private static final char[] AMP_ENCODE = "&".toCharArray();
0026:            private static final char[] LT_ENCODE = "<".toCharArray();
0027:            private static final char[] GT_ENCODE = ">".toCharArray();
0028:
0029:            private StringUtils() {
0030:                // Not instantiable.
0031:            }
0032:
0033:            /**
0034:             * Replaces all instances of oldString with newString in string.
0035:             *
0036:             * @param string the String to search to perform replacements on.
0037:             * @param oldString the String that should be replaced by newString.
0038:             * @param newString the String that will replace all instances of oldString.
0039:             * @return a String will all instances of oldString replaced by newString.
0040:             */
0041:            public static String replace(String string, String oldString,
0042:                    String newString) {
0043:                if (string == null) {
0044:                    return null;
0045:                }
0046:                int i = 0;
0047:                // Make sure that oldString appears at least once before doing any processing.
0048:                if ((i = string.indexOf(oldString, i)) >= 0) {
0049:                    // Use char []'s, as they are more efficient to deal with.
0050:                    char[] string2 = string.toCharArray();
0051:                    char[] newString2 = newString.toCharArray();
0052:                    int oLength = oldString.length();
0053:                    StringBuilder buf = new StringBuilder(string2.length);
0054:                    buf.append(string2, 0, i).append(newString2);
0055:                    i += oLength;
0056:                    int j = i;
0057:                    // Replace all remaining instances of oldString with newString.
0058:                    while ((i = string.indexOf(oldString, i)) > 0) {
0059:                        buf.append(string2, j, i - j).append(newString2);
0060:                        i += oLength;
0061:                        j = i;
0062:                    }
0063:                    buf.append(string2, j, string2.length - j);
0064:                    return buf.toString();
0065:                }
0066:                return string;
0067:            }
0068:
0069:            /**
0070:             * Replaces all instances of oldString with newString in line with the
0071:             * added feature that matches of newString in oldString ignore case.
0072:             *
0073:             * @param line      the String to search to perform replacements on
0074:             * @param oldString the String that should be replaced by newString
0075:             * @param newString the String that will replace all instances of oldString
0076:             * @return a String will all instances of oldString replaced by newString
0077:             */
0078:            public static String replaceIgnoreCase(String line,
0079:                    String oldString, String newString) {
0080:                if (line == null) {
0081:                    return null;
0082:                }
0083:                String lcLine = line.toLowerCase();
0084:                String lcOldString = oldString.toLowerCase();
0085:                int i = 0;
0086:                if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
0087:                    char[] line2 = line.toCharArray();
0088:                    char[] newString2 = newString.toCharArray();
0089:                    int oLength = oldString.length();
0090:                    StringBuilder buf = new StringBuilder(line2.length);
0091:                    buf.append(line2, 0, i).append(newString2);
0092:                    i += oLength;
0093:                    int j = i;
0094:                    while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
0095:                        buf.append(line2, j, i - j).append(newString2);
0096:                        i += oLength;
0097:                        j = i;
0098:                    }
0099:                    buf.append(line2, j, line2.length - j);
0100:                    return buf.toString();
0101:                }
0102:                return line;
0103:            }
0104:
0105:            /**
0106:             * Replaces all instances of oldString with newString in line with the
0107:             * added feature that matches of newString in oldString ignore case.
0108:             * The count paramater is set to the number of replaces performed.
0109:             *
0110:             * @param line      the String to search to perform replacements on
0111:             * @param oldString the String that should be replaced by newString
0112:             * @param newString the String that will replace all instances of oldString
0113:             * @param count     a value that will be updated with the number of replaces
0114:             *                  performed.
0115:             * @return a String will all instances of oldString replaced by newString
0116:             */
0117:            public static String replaceIgnoreCase(String line,
0118:                    String oldString, String newString, int[] count) {
0119:                if (line == null) {
0120:                    return null;
0121:                }
0122:                String lcLine = line.toLowerCase();
0123:                String lcOldString = oldString.toLowerCase();
0124:                int i = 0;
0125:                if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
0126:                    int counter = 1;
0127:                    char[] line2 = line.toCharArray();
0128:                    char[] newString2 = newString.toCharArray();
0129:                    int oLength = oldString.length();
0130:                    StringBuilder buf = new StringBuilder(line2.length);
0131:                    buf.append(line2, 0, i).append(newString2);
0132:                    i += oLength;
0133:                    int j = i;
0134:                    while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
0135:                        counter++;
0136:                        buf.append(line2, j, i - j).append(newString2);
0137:                        i += oLength;
0138:                        j = i;
0139:                    }
0140:                    buf.append(line2, j, line2.length - j);
0141:                    count[0] = counter;
0142:                    return buf.toString();
0143:                }
0144:                return line;
0145:            }
0146:
0147:            /**
0148:             * Replaces all instances of oldString with newString in line.
0149:             * The count Integer is updated with number of replaces.
0150:             *
0151:             * @param line the String to search to perform replacements on.
0152:             * @param oldString the String that should be replaced by newString.
0153:             * @param newString the String that will replace all instances of oldString.
0154:             * @return a String will all instances of oldString replaced by newString.
0155:             */
0156:            public static String replace(String line, String oldString,
0157:                    String newString, int[] count) {
0158:                if (line == null) {
0159:                    return null;
0160:                }
0161:                int i = 0;
0162:                if ((i = line.indexOf(oldString, i)) >= 0) {
0163:                    int counter = 1;
0164:                    char[] line2 = line.toCharArray();
0165:                    char[] newString2 = newString.toCharArray();
0166:                    int oLength = oldString.length();
0167:                    StringBuilder buf = new StringBuilder(line2.length);
0168:                    buf.append(line2, 0, i).append(newString2);
0169:                    i += oLength;
0170:                    int j = i;
0171:                    while ((i = line.indexOf(oldString, i)) > 0) {
0172:                        counter++;
0173:                        buf.append(line2, j, i - j).append(newString2);
0174:                        i += oLength;
0175:                        j = i;
0176:                    }
0177:                    buf.append(line2, j, line2.length - j);
0178:                    count[0] = counter;
0179:                    return buf.toString();
0180:                }
0181:                return line;
0182:            }
0183:
0184:            /**
0185:             * This method takes a string and strips out all tags except <br> tags while still leaving
0186:             * the tag body intact.
0187:             *
0188:             * @param in the text to be converted.
0189:             * @return the input string with all tags removed.
0190:             */
0191:            public static String stripTags(String in) {
0192:                if (in == null) {
0193:                    return null;
0194:                }
0195:                char ch;
0196:                int i = 0;
0197:                int last = 0;
0198:                char[] input = in.toCharArray();
0199:                int len = input.length;
0200:                StringBuilder out = new StringBuilder((int) (len * 1.3));
0201:                for (; i < len; i++) {
0202:                    ch = input[i];
0203:                    if (ch > '>') {
0204:                    } else if (ch == '<') {
0205:                        if (i + 3 < len && input[i + 1] == 'b'
0206:                                && input[i + 2] == 'r' && input[i + 3] == '>') {
0207:                            i += 3;
0208:                            continue;
0209:                        }
0210:                        if (i > last) {
0211:                            out.append(input, last, i - last);
0212:                        }
0213:                        last = i + 1;
0214:                    } else if (ch == '>') {
0215:                        last = i + 1;
0216:                    }
0217:                }
0218:                if (last == 0) {
0219:                    return in;
0220:                }
0221:                if (i > last) {
0222:                    out.append(input, last, i - last);
0223:                }
0224:                return out.toString();
0225:            }
0226:
0227:            /**
0228:             * This method takes a string which may contain HTML tags (ie, &lt;b&gt;,
0229:             * &lt;table&gt;, etc) and converts the '&lt'' and '&gt;' characters to
0230:             * their HTML escape sequences. It will also replace LF  with &lt;br&gt;.
0231:             *
0232:             * @param in the text to be converted.
0233:             * @return the input string with the characters '&lt;' and '&gt;' replaced
0234:             *         with their HTML escape sequences.
0235:             */
0236:            public static String escapeHTMLTags(String in) {
0237:                if (in == null) {
0238:                    return null;
0239:                }
0240:                char ch;
0241:                int i = 0;
0242:                int last = 0;
0243:                char[] input = in.toCharArray();
0244:                int len = input.length;
0245:                StringBuilder out = new StringBuilder((int) (len * 1.3));
0246:                for (; i < len; i++) {
0247:                    ch = input[i];
0248:                    if (ch > '>') {
0249:                    } else if (ch == '<') {
0250:                        if (i > last) {
0251:                            out.append(input, last, i - last);
0252:                        }
0253:                        last = i + 1;
0254:                        out.append(LT_ENCODE);
0255:                    } else if (ch == '>') {
0256:                        if (i > last) {
0257:                            out.append(input, last, i - last);
0258:                        }
0259:                        last = i + 1;
0260:                        out.append(GT_ENCODE);
0261:                    } else if (ch == '\n') {
0262:                        if (i > last) {
0263:                            out.append(input, last, i - last);
0264:                        }
0265:                        last = i + 1;
0266:                        out.append("<br>");
0267:                    }
0268:                }
0269:                if (last == 0) {
0270:                    return in;
0271:                }
0272:                if (i > last) {
0273:                    out.append(input, last, i - last);
0274:                }
0275:                return out.toString();
0276:            }
0277:
0278:            /**
0279:             * Used by the hash method.
0280:             */
0281:            private static Map<String, MessageDigest> digests = new ConcurrentHashMap<String, MessageDigest>();
0282:
0283:            /**
0284:             * Hashes a String using the Md5 algorithm and returns the result as a
0285:             * String of hexadecimal numbers. This method is synchronized to avoid
0286:             * excessive MessageDigest object creation. If calling this method becomes
0287:             * a bottleneck in your code, you may wish to maintain a pool of
0288:             * MessageDigest objects instead of using this method.
0289:             * <p/>
0290:             * A hash is a one-way function -- that is, given an
0291:             * input, an output is easily computed. However, given the output, the
0292:             * input is almost impossible to compute. This is useful for passwords
0293:             * since we can store the hash and a hacker will then have a very hard time
0294:             * determining the original password.
0295:             * <p/>
0296:             * In Jive, every time a user logs in, we simply
0297:             * take their plain text password, compute the hash, and compare the
0298:             * generated hash to the stored hash. Since it is almost impossible that
0299:             * two passwords will generate the same hash, we know if the user gave us
0300:             * the correct password or not. The only negative to this system is that
0301:             * password recovery is basically impossible. Therefore, a reset password
0302:             * method is used instead.
0303:             *
0304:             * @param data the String to compute the hash of.
0305:             * @return a hashed version of the passed-in String
0306:             */
0307:            public static String hash(String data) {
0308:                return hash(data, "MD5");
0309:            }
0310:
0311:            /**
0312:             * Hashes a String using the specified algorithm and returns the result as a
0313:             * String of hexadecimal numbers. This method is synchronized to avoid
0314:             * excessive MessageDigest object creation. If calling this method becomes
0315:             * a bottleneck in your code, you may wish to maintain a pool of
0316:             * MessageDigest objects instead of using this method.
0317:             * <p/>
0318:             * A hash is a one-way function -- that is, given an
0319:             * input, an output is easily computed. However, given the output, the
0320:             * input is almost impossible to compute. This is useful for passwords
0321:             * since we can store the hash and a hacker will then have a very hard time
0322:             * determining the original password.
0323:             * <p/>
0324:             * In Jive, every time a user logs in, we simply
0325:             * take their plain text password, compute the hash, and compare the
0326:             * generated hash to the stored hash. Since it is almost impossible that
0327:             * two passwords will generate the same hash, we know if the user gave us
0328:             * the correct password or not. The only negative to this system is that
0329:             * password recovery is basically impossible. Therefore, a reset password
0330:             * method is used instead.
0331:             *
0332:             * @param data the String to compute the hash of.
0333:             * @param algorithm the name of the algorithm requested.
0334:             * @return a hashed version of the passed-in String
0335:             */
0336:            public static String hash(String data, String algorithm) {
0337:                try {
0338:                    return hash(data.getBytes("utf-8"), algorithm);
0339:                } catch (UnsupportedEncodingException e) {
0340:                    Log.error(e);
0341:                }
0342:                return data;
0343:            }
0344:
0345:            /**
0346:             * Hashes a byte array using the specified algorithm and returns the result as a
0347:             * String of hexadecimal numbers. This method is synchronized to avoid
0348:             * excessive MessageDigest object creation. If calling this method becomes
0349:             * a bottleneck in your code, you may wish to maintain a pool of
0350:             * MessageDigest objects instead of using this method.
0351:             * <p/>
0352:             * A hash is a one-way function -- that is, given an
0353:             * input, an output is easily computed. However, given the output, the
0354:             * input is almost impossible to compute. This is useful for passwords
0355:             * since we can store the hash and a hacker will then have a very hard time
0356:             * determining the original password.
0357:             * <p/>
0358:             * In Jive, every time a user logs in, we simply
0359:             * take their plain text password, compute the hash, and compare the
0360:             * generated hash to the stored hash. Since it is almost impossible that
0361:             * two passwords will generate the same hash, we know if the user gave us
0362:             * the correct password or not. The only negative to this system is that
0363:             * password recovery is basically impossible. Therefore, a reset password
0364:             * method is used instead.
0365:             *
0366:             * @param bytes the byte array to compute the hash of.
0367:             * @param algorithm the name of the algorithm requested.
0368:             * @return a hashed version of the passed-in String
0369:             */
0370:            public static String hash(byte[] bytes, String algorithm) {
0371:                synchronized (algorithm.intern()) {
0372:                    MessageDigest digest = digests.get(algorithm);
0373:                    if (digest == null) {
0374:                        try {
0375:                            digest = MessageDigest.getInstance(algorithm);
0376:                            digests.put(algorithm, digest);
0377:                        } catch (NoSuchAlgorithmException nsae) {
0378:                            Log
0379:                                    .error(
0380:                                            "Failed to load the "
0381:                                                    + algorithm
0382:                                                    + " MessageDigest. "
0383:                                                    + "Jive will be unable to function normally.",
0384:                                            nsae);
0385:                            return null;
0386:                        }
0387:                    }
0388:                    // Now, compute hash.
0389:                    digest.update(bytes);
0390:                    return encodeHex(digest.digest());
0391:                }
0392:            }
0393:
0394:            /**
0395:             * Turns an array of bytes into a String representing each byte as an
0396:             * unsigned hex number.
0397:             * <p/>
0398:             * Method by Santeri Paavolainen, Helsinki Finland 1996<br>
0399:             * (c) Santeri Paavolainen, Helsinki Finland 1996<br>
0400:             * Distributed under LGPL.
0401:             *
0402:             * @param bytes an array of bytes to convert to a hex-string
0403:             * @return generated hex string
0404:             */
0405:            public static String encodeHex(byte[] bytes) {
0406:                StringBuilder buf = new StringBuilder(bytes.length * 2);
0407:                int i;
0408:
0409:                for (i = 0; i < bytes.length; i++) {
0410:                    if (((int) bytes[i] & 0xff) < 0x10) {
0411:                        buf.append("0");
0412:                    }
0413:                    buf.append(Long.toString((int) bytes[i] & 0xff, 16));
0414:                }
0415:                return buf.toString();
0416:            }
0417:
0418:            /**
0419:             * Turns a hex encoded string into a byte array. It is specifically meant
0420:             * to "reverse" the toHex(byte[]) method.
0421:             *
0422:             * @param hex a hex encoded String to transform into a byte array.
0423:             * @return a byte array representing the hex String[
0424:             */
0425:            public static byte[] decodeHex(String hex) {
0426:                char[] chars = hex.toCharArray();
0427:                byte[] bytes = new byte[chars.length / 2];
0428:                int byteCount = 0;
0429:                for (int i = 0; i < chars.length; i += 2) {
0430:                    int newByte = 0x00;
0431:                    newByte |= hexCharToByte(chars[i]);
0432:                    newByte <<= 4;
0433:                    newByte |= hexCharToByte(chars[i + 1]);
0434:                    bytes[byteCount] = (byte) newByte;
0435:                    byteCount++;
0436:                }
0437:                return bytes;
0438:            }
0439:
0440:            /**
0441:             * Returns the the byte value of a hexadecmical char (0-f). It's assumed
0442:             * that the hexidecimal chars are lower case as appropriate.
0443:             *
0444:             * @param ch a hexedicmal character (0-f)
0445:             * @return the byte value of the character (0x00-0x0F)
0446:             */
0447:            private static byte hexCharToByte(char ch) {
0448:                switch (ch) {
0449:                case '0':
0450:                    return 0x00;
0451:                case '1':
0452:                    return 0x01;
0453:                case '2':
0454:                    return 0x02;
0455:                case '3':
0456:                    return 0x03;
0457:                case '4':
0458:                    return 0x04;
0459:                case '5':
0460:                    return 0x05;
0461:                case '6':
0462:                    return 0x06;
0463:                case '7':
0464:                    return 0x07;
0465:                case '8':
0466:                    return 0x08;
0467:                case '9':
0468:                    return 0x09;
0469:                case 'a':
0470:                    return 0x0A;
0471:                case 'b':
0472:                    return 0x0B;
0473:                case 'c':
0474:                    return 0x0C;
0475:                case 'd':
0476:                    return 0x0D;
0477:                case 'e':
0478:                    return 0x0E;
0479:                case 'f':
0480:                    return 0x0F;
0481:                }
0482:                return 0x00;
0483:            }
0484:
0485:            /**
0486:             * Encodes a String as a base64 String.
0487:             *
0488:             * @param data a String to encode.
0489:             * @return a base64 encoded String.
0490:             */
0491:            public static String encodeBase64(String data) {
0492:                byte[] bytes = null;
0493:                try {
0494:                    bytes = data.getBytes("UTF-8");
0495:                } catch (UnsupportedEncodingException uee) {
0496:                    Log.error(uee);
0497:                }
0498:                return encodeBase64(bytes);
0499:            }
0500:
0501:            /**
0502:             * Encodes a byte array into a base64 String.
0503:             *
0504:             * @param data a byte array to encode.
0505:             * @return a base64 encode String.
0506:             */
0507:            public static String encodeBase64(byte[] data) {
0508:                // Encode the String. We pass in a flag to specify that line
0509:                // breaks not be added. This is consistent with our previous base64
0510:                // implementation. Section 2.1 of 3548 (base64 spec) also specifies
0511:                // no line breaks by default.
0512:                return Base64.encodeBytes(data, Base64.DONT_BREAK_LINES);
0513:            }
0514:
0515:            /**
0516:             * Decodes a base64 String.
0517:             *
0518:             * @param data a base64 encoded String to decode.
0519:             * @return the decoded String.
0520:             */
0521:            public static byte[] decodeBase64(String data) {
0522:                return Base64.decode(data);
0523:            }
0524:
0525:            /**
0526:             * Converts a line of text into an array of lower case words using a
0527:             * BreakIterator.wordInstance().<p>
0528:             *
0529:             * This method is under the Jive Open Source Software License and was
0530:             * written by Mark Imbriaco.
0531:             *
0532:             * @param text a String of text to convert into an array of words
0533:             * @return text broken up into an array of words.
0534:             */
0535:            public static String[] toLowerCaseWordArray(String text) {
0536:                if (text == null || text.length() == 0) {
0537:                    return new String[0];
0538:                }
0539:
0540:                List<String> wordList = new ArrayList<String>();
0541:                BreakIterator boundary = BreakIterator.getWordInstance();
0542:                boundary.setText(text);
0543:                int start = 0;
0544:
0545:                for (int end = boundary.next(); end != BreakIterator.DONE; start = end, end = boundary
0546:                        .next()) {
0547:                    String tmp = text.substring(start, end).trim();
0548:                    // Remove characters that are not needed.
0549:                    tmp = replace(tmp, "+", "");
0550:                    tmp = replace(tmp, "/", "");
0551:                    tmp = replace(tmp, "\\", "");
0552:                    tmp = replace(tmp, "#", "");
0553:                    tmp = replace(tmp, "*", "");
0554:                    tmp = replace(tmp, ")", "");
0555:                    tmp = replace(tmp, "(", "");
0556:                    tmp = replace(tmp, "&", "");
0557:                    if (tmp.length() > 0) {
0558:                        wordList.add(tmp);
0559:                    }
0560:                }
0561:                return wordList.toArray(new String[wordList.size()]);
0562:            }
0563:
0564:            /**
0565:             * Pseudo-random number generator object for use with randomString().
0566:             * The Random class is not considered to be cryptographically secure, so
0567:             * only use these random Strings for low to medium security applications.
0568:             */
0569:            private static Random randGen = new Random();
0570:
0571:            /**
0572:             * Array of numbers and letters of mixed case. Numbers appear in the list
0573:             * twice so that there is a more equal chance that a number will be picked.
0574:             * We can use the array to get a random number or letter by picking a random
0575:             * array index.
0576:             */
0577:            private static char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz"
0578:                    + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
0579:
0580:            /**
0581:             * Returns a random String of numbers and letters (lower and upper case)
0582:             * of the specified length. The method uses the Random class that is
0583:             * built-in to Java which is suitable for low to medium grade security uses.
0584:             * This means that the output is only pseudo random, i.e., each number is
0585:             * mathematically generated so is not truly random.<p>
0586:             * <p/>
0587:             * The specified length must be at least one. If not, the method will return
0588:             * null.
0589:             *
0590:             * @param length the desired length of the random String to return.
0591:             * @return a random String of numbers and letters of the specified length.
0592:             */
0593:            public static String randomString(int length) {
0594:                if (length < 1) {
0595:                    return null;
0596:                }
0597:                // Create a char buffer to put random letters and numbers in.
0598:                char[] randBuffer = new char[length];
0599:                for (int i = 0; i < randBuffer.length; i++) {
0600:                    randBuffer[i] = numbersAndLetters[randGen.nextInt(71)];
0601:                }
0602:                return new String(randBuffer);
0603:            }
0604:
0605:            /**
0606:             * Intelligently chops a String at a word boundary (whitespace) that occurs
0607:             * at the specified index in the argument or before. However, if there is a
0608:             * newline character before <code>length</code>, the String will be chopped
0609:             * there. If no newline or whitespace is found in <code>string</code> up to
0610:             * the index <code>length</code>, the String will chopped at <code>length</code>.
0611:             * <p/>
0612:             * For example, chopAtWord("This is a nice String", 10) will return
0613:             * "This is a" which is the first word boundary less than or equal to 10
0614:             * characters into the original String.
0615:             *
0616:             * @param string the String to chop.
0617:             * @param length the index in <code>string</code> to start looking for a
0618:             *               whitespace boundary at.
0619:             * @return a substring of <code>string</code> whose length is less than or
0620:             *         equal to <code>length</code>, and that is chopped at whitespace.
0621:             */
0622:            public static String chopAtWord(String string, int length) {
0623:                if (string == null || string.length() == 0) {
0624:                    return string;
0625:                }
0626:
0627:                char[] charArray = string.toCharArray();
0628:                int sLength = string.length();
0629:                if (length < sLength) {
0630:                    sLength = length;
0631:                }
0632:
0633:                // First check if there is a newline character before length; if so,
0634:                // chop word there.
0635:                for (int i = 0; i < sLength - 1; i++) {
0636:                    // Windows
0637:                    if (charArray[i] == '\r' && charArray[i + 1] == '\n') {
0638:                        return string.substring(0, i + 1);
0639:                    }
0640:                    // Unix
0641:                    else if (charArray[i] == '\n') {
0642:                        return string.substring(0, i);
0643:                    }
0644:                }
0645:                // Also check boundary case of Unix newline
0646:                if (charArray[sLength - 1] == '\n') {
0647:                    return string.substring(0, sLength - 1);
0648:                }
0649:
0650:                // Done checking for newline, now see if the total string is less than
0651:                // the specified chop point.
0652:                if (string.length() < length) {
0653:                    return string;
0654:                }
0655:
0656:                // No newline, so chop at the first whitespace.
0657:                for (int i = length - 1; i > 0; i--) {
0658:                    if (charArray[i] == ' ') {
0659:                        return string.substring(0, i).trim();
0660:                    }
0661:                }
0662:
0663:                // Did not find word boundary so return original String chopped at
0664:                // specified length.
0665:                return string.substring(0, length);
0666:            }
0667:
0668:            /**
0669:             * Reformats a string where lines that are longer than <tt>width</tt>
0670:             * are split apart at the earliest wordbreak or at maxLength, whichever is
0671:             * sooner. If the width specified is less than 5 or greater than the input
0672:             * Strings length the string will be returned as is.
0673:             * <p/>
0674:             * Please note that this method can be lossy - trailing spaces on wrapped
0675:             * lines may be trimmed.
0676:             *
0677:             * @param input the String to reformat.
0678:             * @param width the maximum length of any one line.
0679:             * @return a new String with reformatted as needed.
0680:             */
0681:            public static String wordWrap(String input, int width, Locale locale) {
0682:                // protect ourselves
0683:                if (input == null) {
0684:                    return "";
0685:                } else if (width < 5) {
0686:                    return input;
0687:                } else if (width >= input.length()) {
0688:                    return input;
0689:                }
0690:
0691:                // default locale
0692:                if (locale == null) {
0693:                    locale = JiveGlobals.getLocale();
0694:                }
0695:
0696:                StringBuilder buf = new StringBuilder(input);
0697:                boolean endOfLine = false;
0698:                int lineStart = 0;
0699:
0700:                for (int i = 0; i < buf.length(); i++) {
0701:                    if (buf.charAt(i) == '\n') {
0702:                        lineStart = i + 1;
0703:                        endOfLine = true;
0704:                    }
0705:
0706:                    // handle splitting at width character
0707:                    if (i > lineStart + width - 1) {
0708:                        if (!endOfLine) {
0709:                            int limit = i - lineStart - 1;
0710:                            BreakIterator breaks = BreakIterator
0711:                                    .getLineInstance(locale);
0712:                            breaks.setText(buf.substring(lineStart, i));
0713:                            int end = breaks.last();
0714:
0715:                            // if the last character in the search string isn't a space,
0716:                            // we can't split on it (looks bad). Search for a previous
0717:                            // break character
0718:                            if (end == limit + 1) {
0719:                                if (!Character.isWhitespace(buf
0720:                                        .charAt(lineStart + end))) {
0721:                                    end = breaks.preceding(end - 1);
0722:                                }
0723:                            }
0724:
0725:                            // if the last character is a space, replace it with a \n
0726:                            if (end != BreakIterator.DONE && end == limit + 1) {
0727:                                buf.replace(lineStart + end, lineStart + end
0728:                                        + 1, "\n");
0729:                                lineStart = lineStart + end;
0730:                            }
0731:                            // otherwise, just insert a \n
0732:                            else if (end != BreakIterator.DONE && end != 0) {
0733:                                buf.insert(lineStart + end, '\n');
0734:                                lineStart = lineStart + end + 1;
0735:                            } else {
0736:                                buf.insert(i, '\n');
0737:                                lineStart = i + 1;
0738:                            }
0739:                        } else {
0740:                            buf.insert(i, '\n');
0741:                            lineStart = i + 1;
0742:                            endOfLine = false;
0743:                        }
0744:                    }
0745:                }
0746:
0747:                return buf.toString();
0748:            }
0749:
0750:            /**
0751:             * Escapes all necessary characters in the String so that it can be used in SQL
0752:             *
0753:             * @param string the string to escape.
0754:             * @return the string with appropriate characters escaped.
0755:             */
0756:            public static String escapeForSQL(String string) {
0757:                if (string == null) {
0758:                    return null;
0759:                } else if (string.length() == 0) {
0760:                    return string;
0761:                }
0762:
0763:                char ch;
0764:                char[] input = string.toCharArray();
0765:                int i = 0;
0766:                int last = 0;
0767:                int len = input.length;
0768:                StringBuilder out = null;
0769:                for (; i < len; i++) {
0770:                    ch = input[i];
0771:
0772:                    if (ch == '\'') {
0773:                        if (out == null) {
0774:                            out = new StringBuilder(len + 2);
0775:                        }
0776:                        if (i > last) {
0777:                            out.append(input, last, i - last);
0778:                        }
0779:                        last = i + 1;
0780:                        out.append('\'').append('\'');
0781:                    }
0782:                }
0783:
0784:                if (out == null) {
0785:                    return string;
0786:                } else if (i > last) {
0787:                    out.append(input, last, i - last);
0788:                }
0789:
0790:                return out.toString();
0791:            }
0792:
0793:            /**
0794:             * Escapes all necessary characters in the String so that it can be used
0795:             * in an XML doc.
0796:             *
0797:             * @param string the string to escape.
0798:             * @return the string with appropriate characters escaped.
0799:             */
0800:            public static String escapeForXML(String string) {
0801:                if (string == null) {
0802:                    return null;
0803:                }
0804:                char ch;
0805:                int i = 0;
0806:                int last = 0;
0807:                char[] input = string.toCharArray();
0808:                int len = input.length;
0809:                StringBuilder out = new StringBuilder((int) (len * 1.3));
0810:                for (; i < len; i++) {
0811:                    ch = input[i];
0812:                    if (ch > '>') {
0813:                    } else if (ch == '<') {
0814:                        if (i > last) {
0815:                            out.append(input, last, i - last);
0816:                        }
0817:                        last = i + 1;
0818:                        out.append(LT_ENCODE);
0819:                    } else if (ch == '&') {
0820:                        if (i > last) {
0821:                            out.append(input, last, i - last);
0822:                        }
0823:                        last = i + 1;
0824:                        out.append(AMP_ENCODE);
0825:                    } else if (ch == '"') {
0826:                        if (i > last) {
0827:                            out.append(input, last, i - last);
0828:                        }
0829:                        last = i + 1;
0830:                        out.append(QUOTE_ENCODE);
0831:                    }
0832:                }
0833:                if (last == 0) {
0834:                    return string;
0835:                }
0836:                if (i > last) {
0837:                    out.append(input, last, i - last);
0838:                }
0839:                return out.toString();
0840:            }
0841:
0842:            /**
0843:             * Unescapes the String by converting XML escape sequences back into normal
0844:             * characters.
0845:             *
0846:             * @param string the string to unescape.
0847:             * @return the string with appropriate characters unescaped.
0848:             */
0849:            public static String unescapeFromXML(String string) {
0850:                string = replace(string, "&lt;", "<");
0851:                string = replace(string, "&gt;", ">");
0852:                string = replace(string, "&quot;", "\"");
0853:                return replace(string, "&amp;", "&");
0854:            }
0855:
0856:            private static final char[] zeroArray = "0000000000000000000000000000000000000000000000000000000000000000"
0857:                    .toCharArray();
0858:
0859:            /**
0860:             * Pads the supplied String with 0's to the specified length and returns
0861:             * the result as a new String. For example, if the initial String is
0862:             * "9999" and the desired length is 8, the result would be "00009999".
0863:             * This type of padding is useful for creating numerical values that need
0864:             * to be stored and sorted as character data. Note: the current
0865:             * implementation of this method allows for a maximum <tt>length</tt> of
0866:             * 64.
0867:             *
0868:             * @param string the original String to pad.
0869:             * @param length the desired length of the new padded String.
0870:             * @return a new String padded with the required number of 0's.
0871:             */
0872:            public static String zeroPadString(String string, int length) {
0873:                if (string == null || string.length() > length) {
0874:                    return string;
0875:                }
0876:                StringBuilder buf = new StringBuilder(length);
0877:                buf.append(zeroArray, 0, length - string.length()).append(
0878:                        string);
0879:                return buf.toString();
0880:            }
0881:
0882:            /**
0883:             * Formats a Date as a fifteen character long String made up of the Date's
0884:             * padded millisecond value.
0885:             *
0886:             * @return a Date encoded as a String.
0887:             */
0888:            public static String dateToMillis(Date date) {
0889:                return zeroPadString(Long.toString(date.getTime()), 15);
0890:            }
0891:
0892:            /**
0893:             * Returns a textual representation for the time that has elapsed.
0894:             *
0895:             * @param delta the elapsed time.
0896:             * @return textual representation for the time that has elapsed.
0897:             */
0898:            public static String getElapsedTime(long delta) {
0899:                if (delta < JiveConstants.MINUTE) {
0900:                    return LocaleUtils.getLocalizedString("global.less-minute");
0901:                } else if (delta < JiveConstants.HOUR) {
0902:                    long mins = delta / JiveConstants.MINUTE;
0903:                    StringBuilder sb = new StringBuilder();
0904:                    sb.append(mins).append(" ");
0905:                    sb.append((mins == 1) ? LocaleUtils
0906:                            .getLocalizedString("global.minute") : LocaleUtils
0907:                            .getLocalizedString("global.minutes"));
0908:                    return sb.toString();
0909:                } else if (delta < JiveConstants.DAY) {
0910:                    long hours = delta / JiveConstants.HOUR;
0911:                    delta -= hours * JiveConstants.HOUR;
0912:                    long mins = delta / JiveConstants.MINUTE;
0913:                    StringBuilder sb = new StringBuilder();
0914:                    sb.append(hours).append(" ");
0915:                    sb.append((hours == 1) ? LocaleUtils
0916:                            .getLocalizedString("global.hour") : LocaleUtils
0917:                            .getLocalizedString("global.hours"));
0918:                    sb.append(", ");
0919:                    sb.append(mins).append(" ");
0920:                    sb.append((mins == 1) ? LocaleUtils
0921:                            .getLocalizedString("global.minute") : LocaleUtils
0922:                            .getLocalizedString("global.minutes"));
0923:                    return sb.toString();
0924:                } else {
0925:                    long days = delta / JiveConstants.DAY;
0926:                    delta -= days * JiveConstants.DAY;
0927:                    long hours = delta / JiveConstants.HOUR;
0928:                    delta -= hours * JiveConstants.HOUR;
0929:                    long mins = delta / JiveConstants.MINUTE;
0930:                    StringBuilder sb = new StringBuilder();
0931:                    sb.append(days).append(" ");
0932:                    sb.append((days == 1) ? LocaleUtils
0933:                            .getLocalizedString("global.day") : LocaleUtils
0934:                            .getLocalizedString("global.days"));
0935:                    sb.append(", ");
0936:                    sb.append(hours).append(" ");
0937:                    sb.append((hours == 1) ? LocaleUtils
0938:                            .getLocalizedString("global.hour") : LocaleUtils
0939:                            .getLocalizedString("global.hours"));
0940:                    sb.append(", ");
0941:                    sb.append(mins).append(" ");
0942:                    sb.append((mins == 1) ? LocaleUtils
0943:                            .getLocalizedString("global.minute") : LocaleUtils
0944:                            .getLocalizedString("global.minutes"));
0945:                    return sb.toString();
0946:                }
0947:            }
0948:
0949:            /**
0950:             * Returns a collection of Strings as a comma-delimitted list of strings.
0951:             *
0952:             * @return a String representing the Collection.
0953:             */
0954:            public static String collectionToString(
0955:                    Collection<String> collection) {
0956:                if (collection == null || collection.isEmpty()) {
0957:                    return "";
0958:                }
0959:                StringBuilder buf = new StringBuilder();
0960:                String delim = "";
0961:                for (String element : collection) {
0962:                    buf.append(delim);
0963:                    buf.append(element);
0964:                    delim = ",";
0965:                }
0966:                return buf.toString();
0967:            }
0968:
0969:            /**
0970:             * Returns a comma-delimitted list of Strings as a Collection.
0971:             *
0972:             * @return a Collection representing the String.
0973:             */
0974:            public static Collection<String> stringToCollection(String string) {
0975:                if (string == null || string.trim().length() == 0) {
0976:                    return Collections.emptyList();
0977:                }
0978:                Collection<String> collection = new ArrayList<String>();
0979:                StringTokenizer tokens = new StringTokenizer(string, ",");
0980:                while (tokens.hasMoreTokens()) {
0981:                    collection.add(tokens.nextToken().trim());
0982:                }
0983:                return collection;
0984:            }
0985:
0986:            /**
0987:             * Abbreviates a string to a specified length and then adds an ellipsis
0988:             * if the input is greater than the maxWidth. Example input:
0989:             * <pre>
0990:             *      user1@jivesoftware.com/home
0991:             * </pre>
0992:             * and a maximum length of 20 characters, the abbreviate method will return:
0993:             * <pre>
0994:             *      user1@jivesoftware.c...
0995:             * </pre>
0996:             * @param str the String to abbreviate.
0997:             * @param maxWidth the maximum size of the string, minus the ellipsis.
0998:             * @return the abbreviated String, or <tt>null</tt> if the string was <tt>null</tt>.
0999:             */
1000:            public static String abbreviate(String str, int maxWidth) {
1001:                if (null == str) {
1002:                    return null;
1003:                }
1004:
1005:                if (str.length() <= maxWidth) {
1006:                    return str;
1007:                }
1008:
1009:                return str.substring(0, maxWidth) + "...";
1010:            }
1011:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.