001: /*
002: * Project: Gulden Utilies
003: * Class: de.gulden.util.Toolbox
004: * Version: snapshot-beautyj-1.1
005: *
006: * Date: 2004-09-29
007: *
008: * This is a snapshot version of the Gulden Utilities,
009: * it is not released as a seperate version.
010: *
011: * Note: Contains auto-generated Javadoc comments created by BeautyJ.
012: *
013: * This is licensed under the GNU Lesser General Public License (LGPL)
014: * and comes with NO WARRANTY.
015: *
016: * Author: Jens Gulden
017: * Email: amoda@jensgulden.de
018: */
019:
020: package de.gulden.util;
021:
022: import java.awt.*;
023: import java.net.MalformedURLException;
024: import java.net.URL;
025: import java.util.*;
026: import java.util.Collection;
027: import java.util.List;
028: import java.util.Map;
029: import javax.swing.text.Document;
030:
031: /**
032: * Class Toolbox.
033: *
034: * @author Jens Gulden
035: * @version snapshot-beautyj-1.1
036: */
037: public class Toolbox {
038:
039: // ------------------------------------------------------------------------
040: // --- final static fields ---
041: // ------------------------------------------------------------------------
042:
043: /**
044: * Constant NORTH.
045: */
046: public static final int NORTH = 1;
047:
048: /**
049: * Constant EAST.
050: */
051: public static final int EAST = 2;
052:
053: /**
054: * Constant SOUTH.
055: */
056: public static final int SOUTH = 4;
057:
058: /**
059: * Constant WEST.
060: */
061: public static final int WEST = 8;
062:
063: /**
064: * Constant NORTH_EAST.
065: */
066: public static final int NORTH_EAST = 3;
067:
068: /**
069: * Constant SOUTH_EAST.
070: */
071: public static final int SOUTH_EAST = 6;
072:
073: /**
074: * Constant SOUTH_WEST.
075: */
076: public static final int SOUTH_WEST = 12;
077:
078: /**
079: * Constant NORTH_WEST.
080: */
081: public static final int NORTH_WEST = 9;
082:
083: /**
084: * Constant CENTER.
085: */
086: public static final int CENTER = 0;
087:
088: /**
089: * Constant NL.
090: */
091: public static final String NL = System
092: .getProperty("line.separator");
093:
094: /**
095: * Constant primitiveTypeWrappers[][].
096: */
097: private static final Object[][] primitiveTypeWrappers = {
098: { "boolean", "byte", "short", "int", "long", "float",
099: "double", "char" },
100: { java.lang.Boolean.class, java.lang.Byte.class,
101: java.lang.Short.class, java.lang.Integer.class,
102: java.lang.Long.class, java.lang.Float.class,
103: java.lang.Double.class, java.lang.Character.class } };
104:
105: // ------------------------------------------------------------------------
106: // --- static methods ---
107: // ------------------------------------------------------------------------
108:
109: /**
110: * Returns the primitive type wrapper class.
111: */
112: public static Class getPrimitiveTypeWrapperClass(String typename)
113: throws ClassNotFoundException {
114: int i = getPrimitiveTypeIndex(typename);
115: if (i != -1) {
116: return (Class) primitiveTypeWrappers[1][i];
117: } else {
118: throw new ClassNotFoundException("'" + typename
119: + "' is not a primitive type");
120: }
121: }
122:
123: /**
124: * Returns the primitive type class.
125: */
126: public static Class getPrimitiveTypeClass(String typename)
127: throws ClassNotFoundException {
128: Class wrapper = getPrimitiveTypeWrapperClass(typename);
129: try {
130: java.lang.reflect.Field field = wrapper.getField("TYPE"); // all wrapper classes have public static field TYPE to represent the primitive Class
131: Class primitiveClass = (Class) field.get(null);
132: return primitiveClass;
133: } catch (Exception e) {
134: throw new ClassNotFoundException("wrapper for '" + typename
135: + "' has no TYPE field");
136: }
137: }
138:
139: public static boolean isPrimitiveType(String typename) {
140: return (getPrimitiveTypeIndex(typename) != -1);
141: }
142:
143: /**
144: * Parses the color.
145: */
146: public static Color parseColor(String s) {
147: if ((s.length() == 7) && (s.startsWith("#"))) {
148: String rStr = s.substring(1, 3);
149: String gStr = s.substring(3, 5);
150: String bStr = s.substring(5, 7);
151: int r = decimal(rStr);
152: int g = decimal(gStr);
153: int b = decimal(bStr);
154: return new Color(r, g, b);
155: } else {
156: // try to get from AWT-color-constants
157: try {
158: java.lang.reflect.Field field = Color.class.getField(s);
159: return (Color) field.get(null);
160: } catch (Exception e) {
161: return null; // not found
162: }
163: }
164: }
165:
166: public static String toString(Color color) {
167: return "#" + hex(color.getRed(), 2) + hex(color.getGreen(), 2)
168: + hex(color.getBlue(), 2);
169: }
170:
171: public static String hex(int i) {
172: return Integer.toHexString(i);
173: }
174:
175: public static String hex(int i, int minLength) {
176: String s = hex(i);
177: int lendiff = minLength - s.length();
178: return s + repeat('0', lendiff); // negative values are ok for repeat
179: }
180:
181: public static int decimal(String hex) {
182: return Integer.valueOf(hex, 16).intValue();
183: }
184:
185: public static String repeat(String s, int count) {
186: StringBuffer sb = new StringBuffer();
187: for (int i = 0; i < count; i++) {
188: sb.append(s);
189: }
190: return sb.toString();
191: }
192:
193: public static String repeat(char c, int count) {
194: StringBuffer sb = new StringBuffer();
195: for (int i = 0; i < count; i++) {
196: sb.append(c);
197: }
198: return sb.toString();
199: }
200:
201: public static String noNull(String s) {
202: if (s != null) {
203: return s;
204: } else {
205: return "";
206: }
207: }
208:
209: public static String unqualify(String s) {
210: int pos = s.lastIndexOf('.');
211: if (pos != -1) {
212: return s.substring(pos + 1);
213: } else {
214: return s;
215: }
216: }
217:
218: public static String padRight(String s, String fill, int len) {
219: return s + repeat(fill, len - s.length());
220: }
221:
222: public static String padLeft(String s, String fill, int len) {
223: return repeat(fill, len - s.length()) + s;
224: }
225:
226: /**
227: * Parses the boolean.
228: */
229: public static boolean parseBoolean(String s) {
230: return s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("y")
231: || s.equalsIgnoreCase("on")
232: || s.equalsIgnoreCase("true");
233: }
234:
235: public static String capitalize(String s) {
236: if (s.length() > 0) {
237: return s.substring(0, 1).toUpperCase() + s.substring(1);
238: } else {
239: return "";
240: }
241: }
242:
243: public static String unqualifyJavaName(String name) {
244: int lastDotPos = name.lastIndexOf('.');
245: if (lastDotPos != -1) {
246: return name.substring(lastDotPos + 1);
247: } else {
248: return name;
249: }
250: }
251:
252: /**
253: * Tests if an element is contained in an array, based on a test using equals(...).
254: */
255: public static boolean arrayContains(Object[] array, Object object) {
256: for (int i = 0; i < array.length; i++) {
257: if (object.equals(array[i])) {
258: return true;
259: }
260: }
261: return false;
262: }
263:
264: /**
265: *
266: * @deprecated use isEmpty(String) instead
267: */
268: public static boolean empty(String s) {
269: return isEmpty(s);
270: }
271:
272: public static boolean isEmpty(String s) {
273: return (s == null) || (s.trim().length() == 0);
274: }
275:
276: /**
277: * Returns null if the String has zero size, or is already null itself.
278: * Otherwise returns the string.
279: *
280: * @param s the String to test
281: */
282: public static String emptyNull(String s) {
283: if (s == null || s.length() == 0) {
284: return null;
285: } else {
286: return s;
287: }
288: }
289:
290: public static void centerOnScreen(Component component) {
291: Dimension screen = component.getToolkit().getScreenSize();
292: Dimension comp = component.getSize();
293: Point newLocation = new Point((screen.width - comp.width) / 2,
294: (screen.height - comp.height) / 2);
295: component.setLocation(newLocation);
296: }
297:
298: public static void centerComponent(Component component,
299: Component parent) {
300: Dimension p = parent.getSize();
301: Dimension comp = component.getSize();
302: Point oldPos = parent.getLocation();
303: Point newPos = new Point();
304: newPos.x = oldPos.x + (p.width - comp.width) / 2;
305: newPos.y = oldPos.y + (p.height - comp.height) / 2;
306: component.setLocation(newPos);
307: }
308:
309: public static Object invokeValueOf(Class clazz, String s) {
310: try {
311: Class[] signature = { String.class };
312: java.lang.reflect.Method m = clazz.getMethod("valueOf",
313: signature);
314: Object[] params = { s };
315: Object result = m.invoke(null, params);
316: return result;
317: } catch (Exception e) {
318: return null;
319: }
320: }
321:
322: public static Object invokeMethod(Object o, String methodName,
323: Class[] signature, Object[] parameters) {
324: try {
325: java.lang.reflect.Method m = o.getClass().getMethod(
326: methodName, signature);
327: Object result = m.invoke(o, parameters);
328: return result;
329: } catch (Exception e) {
330: return null;
331: }
332: }
333:
334: public static Object invokeMethod(Object o, String methodName,
335: Class signatureSingle, Object parameterSingle) {
336: return invokeMethod(o, methodName,
337: new Class[] { signatureSingle },
338: new Object[] { parameterSingle });
339: }
340:
341: public static List invokeOnAll(Collection c, String methodName,
342: Class[] signature, Object[] parameter) {
343: List l = new ArrayList();
344: for (Iterator it = c.iterator(); it.hasNext();) {
345: Object o = it.next();
346: Object result = invokeMethod(o, methodName, signature,
347: parameter);
348: l.add(result);
349: }
350: return l;
351: }
352:
353: public static void fireEvent(Collection listeners,
354: String methodName, EventObject event) {
355: invokeOnAll(listeners, methodName, new Class[] { event
356: .getClass() }, new Object[] { event });
357: }
358:
359: /**
360: * Returns the document text.
361: */
362: public static String getDocumentText(Document d) {
363: try {
364: return d.getText(d.getStartPosition().getOffset(), d
365: .getLength());
366: } catch (javax.swing.text.BadLocationException ble) {
367: return null;
368: }
369: }
370:
371: /**
372: * Sets the document text.
373: */
374: public static void setDocumentText(Document d, String s) {
375: try {
376: d.remove(d.getStartPosition().getOffset(), d.getLength());
377: d.insertString(d.getStartPosition().getOffset(), s, null);
378: } catch (javax.swing.text.BadLocationException ble) {
379: throw new Error("INTERNAL ERROR: Toolbox.setDocumentText");
380: }
381: }
382:
383: public static Collection filterCollectionOnType(Collection c,
384: Class type) {
385: Collection result = new ArrayList();
386: for (Iterator it = c.iterator(); it.hasNext();) {
387: Object o = it.next();
388: if (type.isAssignableFrom(o.getClass())) {
389: result.add(o);
390: }
391: }
392: return result;
393: }
394:
395: public static Map filterMapOnType(Map m, Class type) {
396: OrderedHashMap result = new OrderedHashMap();
397: for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
398: Map.Entry entry = (Map.Entry) it.next();
399: if (type.isAssignableFrom(entry.getValue().getClass())) {
400: result.put(entry.getKey(), entry.getValue());
401: }
402: }
403: return result;
404: }
405:
406: public static Component findChildComponent(Container c,
407: Class childType) {
408: Component[] children = c.getComponents();
409: for (int i = 0; i < children.length; i++) {
410: if (childType == children[i].getClass()) {
411: return children[i];
412: }
413: }
414: // if not yet found flatly, recurse search on containers
415: for (int i = 0; i < children.length; i++) {
416: if (children[i] instanceof Container) {
417: Component found = findChildComponent(
418: (Container) children[i], childType);
419: if (found != null) {
420: return found;
421: }
422: }
423: }
424: return null;
425: }
426:
427: public static Component findChildComponentCloseTo(Container c,
428: Class childType, Component anker) {
429: Component[] children = c.getComponents();
430: // find anker index
431: int index = -1;
432: for (int i = 0; (index == -1) && (i < children.length); i++) {
433: if (children[i] == anker) {
434: index = i;
435: }
436: }
437: if (index != -1) {
438: int closest = -1;
439: // find closest instance of requested type
440: for (int i = 0; i < children.length; i++) {
441: if (childType == children[i].getClass()) {
442: if ((closest == -1)
443: || (abs(index - i) < abs(index - closest))) {
444: closest = i;
445: }
446: }
447: }
448: if (closest != -1) {
449: return children[closest];
450: } else {
451: return null;
452: }
453: } else {
454: // if not yet found flatly, recurse search on containers
455: for (int i = 0; i < children.length; i++) {
456: if (children[i] instanceof Container) {
457: Component found = findChildComponentCloseTo(
458: (Container) children[i], childType, anker);
459: if (found != null) {
460: return found;
461: }
462: }
463: }
464: }
465: return null;
466: }
467:
468: public static void drawString(Graphics g, String s, Point p,
469: int anchor, Insets shift, Color backgroundColor,
470: Insets backgroundBorder) {
471: java.awt.FontMetrics fm = g.getFontMetrics();
472: int w = fm.stringWidth(s);
473: int h = fm.getHeight();
474: // AWT draws string anchored at SOUTH_WEST
475: if ((anchor & NORTH) != 0) { // north
476: p.y += (h + shift.top);
477: } else if ((anchor & SOUTH) == 0) { // middle
478: p.y += (h / 2);
479: } else { // south
480: p.y -= shift.bottom;
481: }
482: if ((anchor & EAST) != 0) { // east
483: p.x -= (w + shift.right);
484: } else if ((anchor & WEST) == 0) { // center
485: p.x -= (w / 2);
486: } else { // west
487: p.x += shift.left;
488: }
489: if (backgroundColor != null) {
490: if (backgroundBorder == null) {
491: backgroundBorder = new Insets(0, 0, 0, 0);
492: }
493: Color foregroundColor = g.getColor();
494: g.setColor(backgroundColor);
495: java.awt.Rectangle r = new java.awt.Rectangle();
496: r.x = p.x - backgroundBorder.left;
497: r.y = p.y - fm.getAscent() - backgroundBorder.top;
498: r.width = w + backgroundBorder.left
499: + backgroundBorder.right;
500: r.height = h + backgroundBorder.top
501: + backgroundBorder.bottom;
502: g.fillRect(r.x, r.y, r.width, r.height);
503: g.setColor(foregroundColor);
504: }
505: g.drawString(s, p.x, p.y);
506: }
507:
508: public static void drawString(Graphics g, String s, Point p,
509: int anchor, Insets shift) {
510: drawString(g, s, p, anchor, shift, null, null);
511: }
512:
513: public static void drawString(Graphics g, String s, Point p,
514: int anchor) {
515: drawString(g, s, p, anchor, new Insets(0, 0, 0, 0));
516: }
517:
518: /**
519: * Sets the location centered.
520: */
521: public static void setLocationCentered(Component c, Point p) {
522: Dimension size = c.getSize();
523: c.setLocation(p.x - size.width / 2, p.y - size.height / 2);
524: }
525:
526: public static String replace(String s, String search, String repl) {
527: int pos = s.indexOf(search);
528: if (pos >= 0) {
529: return s.substring(0, pos)
530: + repl
531: + replace(s.substring(pos + search.length()),
532: search, repl);
533: } else {
534: return s;
535: }
536: }
537:
538: public static List explode(String s, char seperator) {
539: StringTokenizer st = new StringTokenizer(s, String
540: .valueOf(seperator), false);
541: List l = new ArrayList();
542: while (st.hasMoreTokens()) {
543: l.add(st.nextToken());
544: }
545: return l;
546: }
547:
548: public static List explode(String s) {
549: return explode(s, ',');
550: }
551:
552: public static String implode(Collection c, char separator) {
553: StringBuffer sb = new StringBuffer();
554: for (Iterator it = c.iterator(); it.hasNext();) {
555: String s = (String) it.next();
556: sb.append(s);
557: if (it.hasNext()) {
558: sb.append(separator);
559: }
560: }
561: return sb.toString();
562: }
563:
564: public static String implode(Collection c) {
565: return implode(c, ',');
566: }
567:
568: /**
569: * Returns the lines.
570: */
571: public static List getLines(String s) {
572: List l = new ArrayList();
573: if ((s != null) && (s.length() > 0)) {
574: int start = 0;
575: int pos = s.indexOf('\n');
576: String line;
577: while (pos != -1) {
578: line = s.substring(start, pos);
579: l.add(line);
580: if (pos < s.length()) {
581: start = pos + 1;
582: pos = s.indexOf('\n', start);
583: } else {
584: pos = -1;
585: }
586: }
587: line = s.substring(start);
588: l.add(line);
589: }
590: return l;
591: }
592:
593: public static boolean isYes(String s) {
594: if (s != null) {
595: s = s.trim().toLowerCase();
596: return (s.equals("yes") || s.equals("true") || s
597: .equals("on"));
598: } else {
599: return false;
600: }
601: }
602:
603: public static boolean isNo(String s) {
604: if (s != null) {
605: s = s.trim().toLowerCase();
606: return (s.equals("no") || s.equals("false") || s
607: .equals("off"));
608: } else {
609: return false;
610: }
611: }
612:
613: public static String replaceCharsWithStrings(String s, char[] c,
614: String[] r) {
615: int len = s.length();
616: StringBuffer sb = new StringBuffer();
617: int[] pos = new int[c.length];
618: int firstIndex = -1;
619: int first = len;
620: int lastPos = 0;
621: // init first positions of each char
622: for (int i = 0; i < c.length; i++) {
623: int p = s.indexOf(c[i]);
624: pos[i] = p;
625: if ((p != -1) && (p < first)) {
626: first = p;
627: firstIndex = i;
628: }
629: }
630: do {
631: String part = s.substring(lastPos, first);
632: sb.append(part);
633: if (first < len) { // firstIndex had been found
634: sb.append(r[firstIndex]);
635: lastPos = first + 1;
636: if (lastPos < len) { // update next pos of this char
637: pos[firstIndex] = s.indexOf(c[firstIndex], lastPos);
638: } else {
639: pos[firstIndex] = -1;
640: }
641: // find new first
642: first = len;
643: for (int i = 0; i < c.length; i++) {
644: int p = pos[i];
645: if ((p != -1) && (p < first)) {
646: first = p;
647: firstIndex = i;
648: }
649: }
650: } else {
651: lastPos = len;
652: }
653: } while (lastPos < len);
654: return sb.toString();
655: }
656:
657: /**
658: * Converts a String to a URL. If the string starts with "res:/",
659: * this leading part is cut off and the URL is created via ClassLoader.getResource().
660: * Otherwise, the URL is created sirectly from the String.
661: */
662: public static URL getResourceURL(String resString)
663: throws MalformedURLException {
664: if (resString.startsWith("res:")) {
665: resString = resString.substring(4);
666: java.net.URL url = ClassLoader.getSystemClassLoader()
667: .getResource(resString);
668: return url;
669: } else {
670: return new java.net.URL(resString);
671: }
672: }
673:
674: public static URL findResource(String resString, Object ref) {
675: return findResource(resString, ref.getClass().getClassLoader());
676: }
677:
678: public static URL findResource(String resString, ClassLoader cl) {
679: // first try to get from current ClassLoader
680: java.net.URL url = (cl != null) ? cl.getResource(resString)
681: : null;
682: // if not found, try to get from system-ClassLoader
683: if (url == null) {
684: url = ClassLoader.getSystemClassLoader().getResource(
685: resString);
686: }
687: return url;
688:
689: }
690:
691: /**
692: * Loads a class and instantiates it.
693: */
694: public static Object instantiateClass(String classname,
695: Class ensureType) throws ClassNotFoundException,
696: IllegalAccessException, InstantiationException {
697: Class cl = Class.forName(classname);
698: if (!ensureType.isAssignableFrom(cl)) {
699: throw new IllegalAccessException(
700: "cannot instantiate class '" + classname
701: + "' - not a subclass/implementation of '"
702: + ensureType.getName() + "'");
703: }
704: return cl.newInstance();
705: }
706:
707: /**
708: * Parse key/value pairs in a string. Key and value are sperated by '='.
709: * the pairs are seperated by whitespace or ';'.
710: * Multiple occurrences of the same key will result in a String[]-array
711: * parse result for that key.
712: *
713: * @param s The string to parse.
714: * @return Properties, with value entries either of type String or String[]
715: */
716: public static Properties parseKeyValuePairs(String s) {
717: // parses strings like: a="val"; b="val"; c="val"...
718: StringTokenizer st = new StringTokenizer(s, " \t\n=\";", false);
719: Properties p = new Properties();
720: while (st.hasMoreTokens()) {
721: String key = st.nextToken();
722: if (st.hasMoreTokens()) {
723: String val = st.nextToken();
724: p.put(key, val);
725: }
726: }
727: return p;
728: }
729:
730: /**
731: * Removes all whitespace at the start of the string.
732: */
733: public static String trimLeft(String s) {
734: int pos = 0;
735: while ((pos < s.length())
736: && (Character.isWhitespace(s.charAt(pos)))) {
737: pos++;
738: }
739: return s.substring(pos);
740: }
741:
742: /**
743: * Removes all whitespace at the end of the string.
744: */
745: public static String trimRight(String s) {
746: int pos = s.length();
747: while ((pos >= 1)
748: && (Character.isWhitespace(s.charAt(pos - 1)))) {
749: pos--;
750: }
751: return s.substring(0, pos);
752: }
753:
754: public static int abs(int i) {
755: if (i >= 0) {
756: return i;
757: } else {
758: return -i;
759: }
760: }
761:
762: /**
763: * Returns the primitive type index.
764: */
765: private static int getPrimitiveTypeIndex(String typename) {
766: for (int i = 0; i < primitiveTypeWrappers[0].length; i++) {
767: if (primitiveTypeWrappers[0][i].equals(typename)) {
768: return i;
769: }
770: }
771: return -1;
772: }
773:
774: } // end Toolbox
|