001: /*
002: * MiscUtils.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.util;
023:
024: import java.awt.event.KeyEvent;
025: import java.io.ByteArrayOutputStream;
026: import java.io.File;
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.lang.reflect.InvocationTargetException;
030: import java.net.MalformedURLException;
031: import java.net.URL;
032: import java.net.URLClassLoader;
033: import java.sql.SQLException;
034: import java.text.DecimalFormat;
035: import java.text.NumberFormat;
036: import java.util.ArrayList;
037: import java.util.Arrays;
038: import java.util.Enumeration;
039: import java.util.Properties;
040: import java.util.StringTokenizer;
041: import java.util.Vector;
042: import java.util.jar.JarFile;
043: import java.util.zip.ZipEntry;
044: import javax.swing.Action;
045: import javax.swing.ActionMap;
046: import javax.swing.InputMap;
047: import javax.swing.JComponent;
048: import javax.swing.KeyStroke;
049:
050: /* ----------------------------------------------------------
051: * CVS NOTE: Changes to the CVS repository prior to the
052: * release of version 3.0.0beta1 has meant a
053: * resetting of CVS revision numbers.
054: * ----------------------------------------------------------
055: */
056:
057: /**
058: *
059: * @author Takis Diakoumis
060: * @author Dragan Vasic
061: * @version $Revision: 1.11 $
062: * @date $Date: 2006/09/24 14:01:08 $
063: */
064: public class MiscUtils {
065:
066: public static final String ACTION_DELIMETER = "+";
067:
068: private static DecimalFormat oneDigitFormat;
069: private static DecimalFormat twoDigitFormat;
070: private static DecimalFormat threeDigitFormat;
071:
072: private MiscUtils() {
073: }
074:
075: /**
076: * Checks if the specified value is <code>null</code>.
077: * This will also return <code>true</code> if the length
078: * of the specified value is zero.
079: *
080: * @param value the value to check for <code>null</code>
081: * @return <code>true</code> | <code>false</code>
082: */
083: public static boolean isNull(String value) {
084: return value == null || value.trim().length() == 0;
085: }
086:
087: /**
088: * Tests if the specified value contains the specified
089: * word as a WHOLE word.
090: *
091: * @param value the value to test for the word
092: * @param word the whole word we are looking for
093: * @return <code>true</code> if found, <code>false</code> otherwise
094: */
095: public static boolean containsWholeWord(String value, String word) {
096:
097: int index = value.indexOf(word);
098:
099: if (index == -1)
100: return false;
101:
102: int valueLength = value.length();
103: int wordLength = word.length();
104: int indexLength = index + wordLength;
105:
106: if (indexLength == valueLength) // same word
107: return true;
108:
109: if (indexLength != valueLength) { // check for embedded word
110:
111: if (index > 0) {
112: return Character
113: .isWhitespace(value.charAt(indexLength))
114: && Character.isWhitespace(value
115: .charAt(index - 1));
116: } else {
117: return Character
118: .isWhitespace(value.charAt(indexLength));
119: }
120:
121: } else {
122: return true;
123: }
124:
125: }
126:
127: public static String getExceptionName(Throwable e) {
128: String exceptionName = "";
129: if (e.getCause() != null) {
130: Throwable _e = e.getCause();
131: exceptionName = _e.getClass().getName();
132: } else {
133: exceptionName = e.getClass().getName();
134: }
135:
136: int index = exceptionName.lastIndexOf('.');
137: if (index != -1) {
138: exceptionName = exceptionName.substring(index + 1);
139: }
140: return exceptionName;
141: }
142:
143: public static String firstLetterToUpper(String value) {
144: boolean nextUpper = false;
145: char[] chars = value.toCharArray();
146: StringBuffer sb = new StringBuffer(chars.length);
147:
148: for (int i = 0; i < chars.length; i++) {
149:
150: if (i == 0 || nextUpper) {
151: sb.append(Character.toUpperCase(chars[i]));
152: nextUpper = false;
153: continue;
154: }
155:
156: if (Character.isWhitespace(chars[i])) {
157: nextUpper = true;
158: sb.append(chars[i]);
159: continue;
160: }
161:
162: sb.append(Character.toLowerCase(chars[i]));
163: nextUpper = false;
164:
165: }
166: return sb.toString();
167: }
168:
169: /**
170: * Formats the specified the SQL exception object
171: * displaying the error message, error code and
172: * the SQL state code.
173: *
174: * @param e - the SQL exception
175: */
176: public static String formatSQLError(SQLException e) {
177: if (e == null) {
178: return "";
179: }
180: StringBuffer sb = new StringBuffer();
181: sb.append(e.getMessage());
182: sb.append("\nError Code: " + e.getErrorCode());
183:
184: String state = e.getSQLState();
185: if (state != null) {
186: sb.append("\nSQL State Code: " + state);
187: }
188: sb.append("\n");
189: return sb.toString();
190: }
191:
192: /**
193: * Returns a <code>String</code> array of the the CSV value
194: * specified with the specfied delimiter.
195: *
196: * @param csvString the CSV value
197: * @param delim the delimiter used in the CSV value
198: * @return an array of split values
199: */
200: public static String[] splitSeparatedValues(String csvString,
201: String delim) {
202: StringTokenizer st = new StringTokenizer(csvString, delim);
203: ArrayList list = new ArrayList(st.countTokens());
204:
205: while (st.hasMoreTokens()) {
206: list.add(st.nextToken());
207: }
208:
209: String[] values = (String[]) list.toArray(new String[list
210: .size()]);
211: return values;
212: }
213:
214: public static boolean containsValue(String[] values, String value) {
215:
216: for (int i = 0; i < values.length; i++) {
217:
218: if (values[i].compareTo(value) == 0) {
219: return true;
220: }
221:
222: }
223:
224: return false;
225:
226: }
227:
228: public static boolean isValidNumber(String number) {
229: char[] chars = number.toCharArray();
230:
231: for (int i = 0; i < chars.length; i++) {
232:
233: if (!Character.isDigit(chars[i])) {
234: return false;
235: }
236:
237: }
238:
239: return true;
240:
241: }
242:
243: public static String getClassName(String path) {
244: int index = path.indexOf(".class");
245:
246: if (index == -1) {
247: return null;
248: }
249:
250: char dot = '.';
251: char pathSeparator = '/';
252: char[] chars = path.toCharArray();
253: StringBuffer sb = new StringBuffer(chars.length);
254:
255: for (int i = 0; i < chars.length; i++) {
256:
257: if (i == index) {
258: break;
259: }
260:
261: if (chars[i] == pathSeparator) {
262: sb.append(dot);
263: } else {
264: sb.append(chars[i]);
265: }
266:
267: }
268:
269: return sb.toString();
270: }
271:
272: public static String[] findImplementingClasses(
273: String interfaceName, String paths)
274: throws MalformedURLException, IOException {
275: return findImplementingClasses(interfaceName, paths, true);
276: }
277:
278: public static String[] findImplementingClasses(
279: String interfaceName, String paths, boolean interfaceOnly)
280: throws MalformedURLException, IOException {
281:
282: URL[] urls = loadURLs(paths);
283: URLClassLoader loader = new URLClassLoader(urls, ClassLoader
284: .getSystemClassLoader());
285:
286: JarFile jarFile = null;
287: String className = null;
288: String[] files = splitSeparatedValues(paths, ";");
289: ArrayList clazzes = new ArrayList();
290:
291: for (int i = 0; i < files.length; i++) {
292:
293: jarFile = new JarFile(files[i]);
294:
295: for (Enumeration j = jarFile.entries(); j.hasMoreElements();) {
296: ZipEntry entry = (ZipEntry) j.nextElement();
297: className = getClassName(entry.getName());
298:
299: if (className == null) {
300: continue;
301: }
302:
303: try {
304: Class clazz = loader.loadClass(className);
305:
306: if (clazz.isInterface()) {
307: continue;
308: }
309:
310: String name = getImplementedClass(clazz,
311: interfaceName);
312: if (name != null) {
313: clazzes.add(className);
314: }
315:
316: if (!interfaceOnly) {
317: Class _clazz = clazz;
318: Class super Clazz = null;
319: while ((super Clazz = _clazz.getSuperclass()) != null) {
320: name = super Clazz.getName();
321: if (interfaceName.compareTo(name) == 0) {
322: clazzes.add(clazz.getName());
323: break;
324: }
325: _clazz = super Clazz;
326: }
327:
328: }
329:
330: }
331: // ignore - noticed with oracle 10g driver only
332: catch (NoClassDefFoundError e) {
333: }
334: // ignore and continue
335: catch (Exception e) {
336: }
337:
338: }
339:
340: }
341: return (String[]) clazzes.toArray(new String[clazzes.size()]);
342: }
343:
344: public static String getImplementedClass(Class clazz,
345: String implementation) {
346: Class[] interfaces = clazz.getInterfaces();
347:
348: for (int k = 0; k < interfaces.length; k++) {
349: String interfaceName = interfaces[k].getName();
350: if (interfaceName.compareTo(implementation) == 0) {
351: return clazz.getName();
352: }
353: }
354:
355: Class super Clazz = clazz.getSuperclass();
356:
357: if (super Clazz != null) {
358: return getImplementedClass(super Clazz, implementation);
359: }
360:
361: return null;
362: }
363:
364: public static URL[] loadURLs(String paths)
365: throws MalformedURLException {
366: String token = ";";
367: Vector pathsVector = new Vector();
368:
369: if (paths.indexOf(token) != -1) {
370: StringTokenizer st = new StringTokenizer(paths, token);
371: while (st.hasMoreTokens()) {
372: pathsVector.add(st.nextToken());
373: }
374: } else {
375: pathsVector.add(paths);
376: }
377:
378: URL[] urls = new URL[pathsVector.size()];
379: for (int i = 0; i < urls.length; i++) {
380: File f = new File((String) pathsVector.elementAt(i));
381: urls[i] = f.toURL();
382: }
383: return urls;
384: }
385:
386: public static String formatNumber(long number, String pattern) {
387: NumberFormat nf = NumberFormat.getNumberInstance();
388: DecimalFormat df = (DecimalFormat) nf;
389: df.applyPattern(pattern);
390: return df.format(number);
391: }
392:
393: public static String keyStrokeToString(KeyStroke keyStroke) {
394: String value = null;
395: if (keyStroke != null) {
396: int mod = keyStroke.getModifiers();
397: value = KeyEvent.getKeyModifiersText(mod);
398:
399: if (!MiscUtils.isNull(value)) {
400: value += ACTION_DELIMETER;
401: }
402:
403: String keyText = KeyEvent
404: .getKeyText(keyStroke.getKeyCode());
405:
406: if (!MiscUtils.isNull(keyText)) {
407: value += keyText;
408: }
409:
410: }
411: return value;
412: }
413:
414: /**
415: * Returns the system properties from <code>System.getProperties()</code>
416: * as a 2 dimensional array of key/name.
417: */
418: public static String[][] getSystemProperties() {
419: Properties sysProps = System.getProperties();
420: String[] keys = new String[sysProps.size()];
421:
422: int count = 0;
423: for (Enumeration i = sysProps.propertyNames(); i
424: .hasMoreElements();) {
425: keys[count++] = (String) i.nextElement();
426: }
427:
428: Arrays.sort(keys);
429: String[][] properties = new String[keys.length][2];
430: for (int i = 0; i < keys.length; i++) {
431: properties[i][0] = keys[i];
432: properties[i][1] = sysProps.getProperty(keys[i]);
433: }
434: return properties;
435: }
436:
437: /**
438: * Prints the system properties as [key: name].
439: */
440: public static void printSystemProperties() {
441: String[][] properties = getSystemProperties();
442: for (int i = 0; i < properties.length; i++) {
443: System.out.println(properties[i][0] + ":\t"
444: + properties[i][1]);
445: }
446: }
447:
448: public static void printActionMap(JComponent component) {
449: printActionMap(component.getActionMap(), component.getClass()
450: .getName());
451: }
452:
453: public static void printInputMap(JComponent component) {
454: printInputMap(component.getInputMap(JComponent.WHEN_FOCUSED),
455: "Input map used when focused");
456: printInputMap(
457: component
458: .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT),
459: "Input map used when ancestor of focused component");
460: printInputMap(component
461: .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW),
462: "Input map used when in focused window");
463: }
464:
465: public static void printActionMap(ActionMap actionMap, String who) {
466: System.out.println("Action map for " + who + ":");
467: Object[] keys = actionMap.allKeys();
468: if (keys != null) {
469: for (int i = 0; i < keys.length; i++) {
470: Object key = keys[i];
471: Action targetAction = actionMap.get(key);
472: System.out.println("\tName: <" + key + ">, action: "
473: + targetAction.getClass().getName());
474: }
475: }
476: }
477:
478: public static void printInputMap(InputMap inputMap, String heading) {
479: System.out.println("\n" + heading + ":");
480: KeyStroke[] keys = inputMap.allKeys();
481: if (keys != null) {
482: for (int i = 0; i < keys.length; i++) {
483: KeyStroke key = keys[i];
484: Object actionName = inputMap.get(key);
485: System.out.println("\tKey: <" + key
486: + ">, action name: " + actionName);
487: }
488: }
489: }
490:
491: public static String formatDuration(long value) {
492:
493: if (twoDigitFormat == null || oneDigitFormat == null) {
494: oneDigitFormat = new DecimalFormat("0");
495: twoDigitFormat = new DecimalFormat("00");
496: //threeDigitFormat = new DecimalFormat("000");
497: }
498:
499: // {"milliseconds","seconds","minutes","hours"}
500: long[] divisors = { 1000, 60, 60, 24 };
501: double[] result = new double[divisors.length];
502:
503: for (int i = 0; i < divisors.length; i++) {
504: result[i] = value % divisors[i];
505: value /= divisors[i];
506: }
507: /*
508: String[] labels = {"milliseconds","seconds","minutes","hours"};
509: for(int i = divisors.length-1;i >= 0;i--) {
510: System.out.print(" " + result[i] + " " + labels[i]);
511: }
512: System.out.println();
513: */
514:
515: //build "hh:mm:ss.SSS"
516: StringBuffer buffer = new StringBuffer(" ");
517: buffer.append(oneDigitFormat.format(result[3]));
518: buffer.append(':');
519: buffer.append(twoDigitFormat.format(result[2]));
520: buffer.append(':');
521: buffer.append(twoDigitFormat.format(result[1]));
522: buffer.append('.');
523: buffer.append(twoDigitFormat.format(result[0]));
524:
525: return buffer.toString();
526: }
527:
528: public static boolean getBooleanValue(String value) {
529: return Boolean.valueOf(value).booleanValue();
530: }
531:
532: public static String charsToString(char[] chars) {
533: StringBuffer sb = new StringBuffer(chars.length);
534: for (int i = 0; i < chars.length; i++) {
535: sb.append(chars[i]);
536: }
537: return sb.toString();
538: }
539:
540: /**
541: * Returns whether the current version of the JVM is at least
542: * that specified for major and minor version numbers. For example,
543: * with a minium required of 1.4, the major version is 1 and minor is 4.
544: *
545: * @param major - the major version
546: * @param minor - the minor version
547: * @return whether the system version is at least major.minor
548: */
549: public static boolean isMinJavaVersion(int major, int minor) {
550: //String version = System.getProperty("java.vm.version");
551: String version = System.getProperty("java.version");
552: String installedVersion = version;
553:
554: int index = version.indexOf("_");
555: if (index > 0) {
556: installedVersion = version.substring(0, index);
557: }
558:
559: String[] installed = splitSeparatedValues(installedVersion, ".");
560:
561: // expect to get something like x.x.x - need at least x.x
562: if (installed.length < 2) {
563: return false;
564: }
565:
566: // major at position 0
567: int _version = Integer.parseInt(installed[0]);
568: if (_version < major) {
569: return false;
570: }
571:
572: _version = Integer.parseInt(installed[1]);
573: if (_version < minor) {
574: return false;
575: }
576:
577: return true;
578: }
579:
580: public static byte[] inputStreamToBytes(InputStream is) {
581: byte[] retVal = new byte[0];
582: ByteArrayOutputStream baos = new ByteArrayOutputStream();
583: if (is != null) {
584: byte[] elementi = new byte[10000];
585: int size = 0;
586: try {
587: while ((size = is.read(elementi)) != -1) {
588: //retVal = addBytes(retVal,elementi,(retVal.length),size);
589: System.out.print(".");
590: baos.write(elementi, 0, size);
591: }
592: retVal = baos.toByteArray();
593: } catch (IOException e) {
594: e.printStackTrace();
595: } catch (Exception e) {
596: e.printStackTrace();
597: retVal = new byte[0];
598: }
599: }
600: return retVal;
601: }
602:
603: }
|