001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jface.util;
011:
012: import java.util.Collections;
013: import java.util.List;
014: import java.util.MissingResourceException;
015: import java.util.ResourceBundle;
016: import java.util.SortedSet;
017: import java.util.TreeSet;
018:
019: /**
020: * <p>
021: * A static class providing utility methods to all of JFace.
022: * </p>
023: *
024: * @since 3.1
025: */
026: public final class Util {
027:
028: /**
029: * An unmodifiable, empty, sorted set. This value is guaranteed to never
030: * change and never be <code>null</code>.
031: */
032: public static final SortedSet EMPTY_SORTED_SET = Collections
033: .unmodifiableSortedSet(new TreeSet());
034:
035: /**
036: * A common zero-length string. It avoids needing write <code>NON-NLS</code>
037: * next to code fragments. It's also a bit clearer to read.
038: */
039: public static final String ZERO_LENGTH_STRING = ""; //$NON-NLS-1$
040:
041: /**
042: * Verifies that the given object is an instance of the given class.
043: *
044: * @param object
045: * The object to check; may be <code>null</code>.
046: * @param c
047: * The class which the object should be; must not be
048: * <code>null</code>.
049: */
050: public static final void assertInstance(final Object object,
051: final Class c) {
052: assertInstance(object, c, false);
053: }
054:
055: /**
056: * Verifies the given object is an instance of the given class. It is
057: * possible to specify whether the object is permitted to be
058: * <code>null</code>.
059: *
060: * @param object
061: * The object to check; may be <code>null</code>.
062: * @param c
063: * The class which the object should be; must not be
064: * <code>null</code>.
065: * @param allowNull
066: * Whether the object is allowed to be <code>null</code>.
067: */
068: private static final void assertInstance(final Object object,
069: final Class c, final boolean allowNull) {
070: if (object == null && allowNull) {
071: return;
072: }
073:
074: if (object == null || c == null) {
075: throw new NullPointerException();
076: } else if (!c.isInstance(object)) {
077: throw new IllegalArgumentException();
078: }
079: }
080:
081: /**
082: * Compares two boolean values. <code>false</code> is considered to be
083: * "less than" <code>true</code>.
084: *
085: * @param left
086: * The left value to compare
087: * @param right
088: * The right value to compare
089: * @return <code>-1</code> if the left is <code>false</code> and the
090: * right is <code>true</code>. <code>1</code> if the opposite
091: * is true. If they are equal, then it returns <code>0</code>.
092: */
093: public static final int compare(final boolean left,
094: final boolean right) {
095: return left == false ? (right == true ? -1 : 0) : 1;
096: }
097:
098: /**
099: * Compares two integer values.
100: *
101: * @param left
102: * The left value to compare
103: * @param right
104: * The right value to compare
105: * @return <code>left - right</code>
106: */
107: public static final int compare(final int left, final int right) {
108: return left - right;
109: }
110:
111: /**
112: * Compares to comparable objects -- defending against <code>null</code>.
113: *
114: * @param left
115: * The left object to compare; may be <code>null</code>.
116: * @param right
117: * The right object to compare; may be <code>null</code>.
118: * @return The result of the comparison. <code>null</code> is considered
119: * to be the least possible value.
120: */
121: public static final int compare(final Comparable left,
122: final Comparable right) {
123: if (left == null && right == null) {
124: return 0;
125: } else if (left == null) {
126: return -1;
127: } else if (right == null) {
128: return 1;
129: } else {
130: return left.compareTo(right);
131: }
132: }
133:
134: /**
135: * Compares two arrays of comparable objects -- accounting for
136: * <code>null</code>.
137: *
138: * @param left
139: * The left array to be compared; may be <code>null</code>.
140: * @param right
141: * The right array to be compared; may be <code>null</code>.
142: * @return The result of the comparison. <code>null</code> is considered
143: * to be the least possible value. A shorter array is considered
144: * less than a longer array.
145: */
146: public static final int compare(final Comparable[] left,
147: final Comparable[] right) {
148: if (left == null && right == null) {
149: return 0;
150: } else if (left == null) {
151: return -1;
152: } else if (right == null) {
153: return 1;
154: } else {
155: int l = left.length;
156: int r = right.length;
157:
158: if (l != r) {
159: return l - r;
160: }
161:
162: for (int i = 0; i < l; i++) {
163: int compareTo = compare(left[i], right[i]);
164:
165: if (compareTo != 0) {
166: return compareTo;
167: }
168: }
169:
170: return 0;
171: }
172: }
173:
174: /**
175: * Compares two lists -- account for <code>null</code>. The lists must
176: * contain comparable objects.
177: *
178: * @param left
179: * The left list to compare; may be <code>null</code>. This
180: * list must only contain instances of <code>Comparable</code>.
181: * @param right
182: * The right list to compare; may be <code>null</code>. This
183: * list must only contain instances of <code>Comparable</code>.
184: * @return The result of the comparison. <code>null</code> is considered
185: * to be the least possible value. A shorter list is considered less
186: * than a longer list.
187: */
188: public static final int compare(final List left, final List right) {
189: if (left == null && right == null) {
190: return 0;
191: } else if (left == null) {
192: return -1;
193: } else if (right == null) {
194: return 1;
195: } else {
196: int l = left.size();
197: int r = right.size();
198:
199: if (l != r) {
200: return l - r;
201: }
202:
203: for (int i = 0; i < l; i++) {
204: int compareTo = compare((Comparable) left.get(i),
205: (Comparable) right.get(i));
206:
207: if (compareTo != 0) {
208: return compareTo;
209: }
210: }
211:
212: return 0;
213: }
214: }
215:
216: /**
217: * Tests whether the first array ends with the second array.
218: *
219: * @param left
220: * The array to check (larger); may be <code>null</code>.
221: * @param right
222: * The array that should be a subsequence (smaller); may be
223: * <code>null</code>.
224: * @param equals
225: * Whether the two array are allowed to be equal.
226: * @return <code>true</code> if the second array is a subsequence of the
227: * array list, and they share end elements.
228: */
229: public static final boolean endsWith(final Object[] left,
230: final Object[] right, final boolean equals) {
231: if (left == null || right == null) {
232: return false;
233: }
234:
235: int l = left.length;
236: int r = right.length;
237:
238: if (r > l || !equals && r == l) {
239: return false;
240: }
241:
242: for (int i = 0; i < r; i++) {
243: if (!equals(left[l - i - 1], right[r - i - 1])) {
244: return false;
245: }
246: }
247:
248: return true;
249: }
250:
251: /**
252: * Checks whether the two objects are <code>null</code> -- allowing for
253: * <code>null</code>.
254: *
255: * @param left
256: * The left object to compare; may be <code>null</code>.
257: * @param right
258: * The right object to compare; may be <code>null</code>.
259: * @return <code>true</code> if the two objects are equivalent;
260: * <code>false</code> otherwise.
261: */
262: public static final boolean equals(final Object left,
263: final Object right) {
264: return left == null ? right == null : ((right != null) && left
265: .equals(right));
266: }
267:
268: /**
269: * Tests whether two arrays of objects are equal to each other. The arrays
270: * must not be <code>null</code>, but their elements may be
271: * <code>null</code>.
272: *
273: * @param leftArray
274: * The left array to compare; may be <code>null</code>, and
275: * may be empty and may contain <code>null</code> elements.
276: * @param rightArray
277: * The right array to compare; may be <code>null</code>, and
278: * may be empty and may contain <code>null</code> elements.
279: * @return <code>true</code> if the arrays are equal length and the
280: * elements at the same position are equal; <code>false</code>
281: * otherwise.
282: */
283: public static final boolean equals(final Object[] leftArray,
284: final Object[] rightArray) {
285: if (leftArray == rightArray) {
286: return true;
287: }
288:
289: if (leftArray == null) {
290: return (rightArray == null);
291: } else if (rightArray == null) {
292: return false;
293: }
294:
295: if (leftArray.length != rightArray.length) {
296: return false;
297: }
298:
299: for (int i = 0; i < leftArray.length; i++) {
300: final Object left = leftArray[i];
301: final Object right = rightArray[i];
302: final boolean equal = (left == null) ? (right == null)
303: : (left.equals(right));
304: if (!equal) {
305: return false;
306: }
307: }
308:
309: return true;
310: }
311:
312: /**
313: * Provides a hash code based on the given integer value.
314: *
315: * @param i
316: * The integer value
317: * @return <code>i</code>
318: */
319: public static final int hashCode(final int i) {
320: return i;
321: }
322:
323: /**
324: * Provides a hash code for the object -- defending against
325: * <code>null</code>.
326: *
327: * @param object
328: * The object for which a hash code is required.
329: * @return <code>object.hashCode</code> or <code>0</code> if
330: * <code>object</code> if <code>null</code>.
331: */
332: public static final int hashCode(final Object object) {
333: return object != null ? object.hashCode() : 0;
334: }
335:
336: /**
337: * Computes the hash code for an array of objects, but with defense against
338: * <code>null</code>.
339: *
340: * @param objects
341: * The array of objects for which a hash code is needed; may be
342: * <code>null</code>.
343: * @return The hash code for <code>objects</code>; or <code>0</code> if
344: * <code>objects</code> is <code>null</code>.
345: */
346: public static final int hashCode(final Object[] objects) {
347: if (objects == null) {
348: return 0;
349: }
350:
351: int hashCode = 89;
352: for (int i = 0; i < objects.length; i++) {
353: final Object object = objects[i];
354: if (object != null) {
355: hashCode = hashCode * 31 + object.hashCode();
356: }
357: }
358:
359: return hashCode;
360: }
361:
362: /**
363: * Checks whether the second array is a subsequence of the first array, and
364: * that they share common starting elements.
365: *
366: * @param left
367: * The first array to compare (large); may be <code>null</code>.
368: * @param right
369: * The second array to compare (small); may be <code>null</code>.
370: * @param equals
371: * Whether it is allowed for the two arrays to be equivalent.
372: * @return <code>true</code> if the first arrays starts with the second
373: * list; <code>false</code> otherwise.
374: */
375: public static final boolean startsWith(final Object[] left,
376: final Object[] right, final boolean equals) {
377: if (left == null || right == null) {
378: return false;
379: }
380:
381: int l = left.length;
382: int r = right.length;
383:
384: if (r > l || !equals && r == l) {
385: return false;
386: }
387:
388: for (int i = 0; i < r; i++) {
389: if (!equals(left[i], right[i])) {
390: return false;
391: }
392: }
393:
394: return true;
395: }
396:
397: /**
398: * Converts an array into a string representation that is suitable for
399: * debugging.
400: *
401: * @param array
402: * The array to convert; may be <code>null</code>.
403: * @return The string representation of the array; never <code>null</code>.
404: */
405: public static final String toString(final Object[] array) {
406: if (array == null) {
407: return "null"; //$NON-NLS-1$
408: }
409:
410: final StringBuffer buffer = new StringBuffer();
411: buffer.append('[');
412:
413: final int length = array.length;
414: for (int i = 0; i < length; i++) {
415: if (i != 0) {
416: buffer.append(',');
417: }
418: final Object object = array[i];
419: final String element = String.valueOf(object);
420: buffer.append(element);
421: }
422: buffer.append(']');
423:
424: return buffer.toString();
425: }
426:
427: /**
428: * Provides a translation of a particular key from the resource bundle.
429: *
430: * @param resourceBundle
431: * The key to look up in the resource bundle; should not be
432: * <code>null</code>.
433: * @param key
434: * The key to look up in the resource bundle; should not be
435: * <code>null</code>.
436: * @param defaultString
437: * The value to return if the resource cannot be found; may be
438: * <code>null</code>.
439: * @return The value of the translated resource at <code>key</code>. If
440: * the key cannot be found, then it is simply the
441: * <code>defaultString</code>.
442: */
443: public static final String translateString(
444: final ResourceBundle resourceBundle, final String key,
445: final String defaultString) {
446: if (resourceBundle != null && key != null) {
447: try {
448: final String translatedString = resourceBundle
449: .getString(key);
450:
451: if (translatedString != null) {
452: return translatedString;
453: }
454: } catch (MissingResourceException eMissingResource) {
455: // Such is life. We'll return the key
456: }
457: }
458:
459: return defaultString;
460: }
461:
462: /**
463: * This class should never be constructed.
464: */
465: private Util() {
466: // Not allowed.
467: }
468: }
|