001 /*
002 * Copyright 2006 Mat Gessel <mat.gessel@gmail.com>
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package asquare.gwt.tk.client.util;
017
018 import java.util.List;
019
020 /**
021 * General utility methods for working with in GWT.
022 */
023 public class GwtUtil
024 {
025 /**
026 * Checks that the specified index is valid for the list (the GWT emulation
027 * of {@link java.util.Vector Vector} does not perform range checking). A
028 * flag is passed to indicate whether the range should be extended by 1 to
029 * allow for adding a last element. Throws an exception if the index is out
030 * of bounds for the list.
031 *
032 * @param list the list to check against
033 * @param index the index to range check
034 * @param adding <code>true</code> to allow for
035 * {@link List#add(int, java.lang.Object) adding} at the index
036 * after last element in list
037 * @throws IndexOutOfBoundsException if the index is out of range
038 */
039 public static void rangeCheck(List list, int index, boolean adding) throws IndexOutOfBoundsException
040 {
041 rangeCheck(0, list.size(), index, adding);
042 }
043
044 /**
045 * Checks that a number is contained within the specified range. A flag is
046 * passed to indicate whether the range should be extended by 1 (to allow
047 * for adding a last element). Throws an exception if the index is out of
048 * bounds for the range.
049 *
050 * @param first the first allowable number
051 * @param size the size of the allowed range
052 * @param n the index to range check
053 * @param extend <code>true</code> to extend the size of the range by
054 * <code>1</code>
055 * @throws IndexOutOfBoundsException if the index is out of range
056 */
057 public static void rangeCheck(int first, int size, int n, boolean extend) throws IndexOutOfBoundsException
058 {
059 if (n < first || n > (first + size) || (! extend) && n == (first + size))
060 throw new IndexOutOfBoundsException(Integer.toString(n));
061 }
062
063 /**
064 * Copies elements from the <code>src</code> array to the <code>dest</code> array.
065 *
066 * @param src the source array
067 * @param srcPos the starting position in the source array
068 * @param dest the destination array
069 * @param destPos the starting position in the destination array
070 * @param length the number of array elements to copy
071 * @throws NullPointerException if <code>src</code> or <code>dest</code> is <code>null</code>
072 * @throws IndexOutOfBoundsException if <code>srcPos < 0 || destPos < 0 || length < 0 || (srcPos + length > src.length) || (destPos + length > dest.length)</code>
073 * @throws ArrayStoreException if an element in <code>src</code> cannot not be copied to <code>dest</code> due to a type mismatch
074 * @see System#arraycopy(Object, int, Object, int, int)
075 */
076 public static void arrayCopy(Object src, int srcPos, Object dest, int destPos, int length)
077 {
078 // need to check srcPos and destPos for script mode
079 if (length < 0 || srcPos < 0 || destPos < 0)
080 throw new IndexOutOfBoundsException();
081
082 if (src instanceof Object[] && dest instanceof Object[])
083 {
084 arrayCopy((Object[]) src, srcPos, (Object[]) dest, destPos, length);
085 }
086 else if (src instanceof int[] && dest instanceof int[])
087 {
088 arrayCopy((int[]) src, srcPos, (int[]) dest, destPos, length);
089 }
090 else if (src instanceof boolean[] && dest instanceof boolean[])
091 {
092 arrayCopy((boolean[]) src, srcPos, (boolean[]) dest, destPos, length);
093 }
094 else if (src instanceof float[] && dest instanceof float[])
095 {
096 arrayCopy((float[]) src, srcPos, (float[]) dest, destPos, length);
097 }
098 else if (src instanceof char[] && dest instanceof char[])
099 {
100 arrayCopy((char[]) src, srcPos, (char[]) dest, destPos, length);
101 }
102 else if (src instanceof byte[] && dest instanceof byte[])
103 {
104 arrayCopy((byte[]) src, srcPos, (byte[]) dest, destPos, length);
105 }
106 else if (src instanceof short[] && dest instanceof short[])
107 {
108 arrayCopy((short[]) src, srcPos, (short[]) dest, destPos, length);
109 }
110 else if (src instanceof long[] && dest instanceof long[])
111 {
112 arrayCopy((long[]) src, srcPos, (long[]) dest, destPos, length);
113 }
114 else if (src instanceof double[] && dest instanceof double[])
115 {
116 arrayCopy((double[]) src, srcPos, (double[]) dest, destPos, length);
117 }
118 else if (src == null || dest == null)
119 {
120 throw new NullPointerException();
121 }
122 else
123 {
124 throw new ArrayStoreException();
125 }
126 }
127
128 private static void arrayCopy(Object[] src, int srcPos, Object[] dest, int destPos, int length)
129 {
130 if (srcPos + length > src.length || destPos + length > dest.length)
131 throw new IndexOutOfBoundsException();
132
133 for (int i = 0; i < length; i++)
134 {
135 dest[destPos + i] = src[srcPos + i];
136 }
137 }
138
139 private static void arrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length)
140 {
141 if (srcPos + length > src.length || destPos + length > dest.length)
142 throw new IndexOutOfBoundsException();
143
144 for (int i = 0; i < length; i++)
145 {
146 dest[destPos + i] = src[srcPos + i];
147 }
148 }
149
150 private static void arrayCopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length)
151 {
152 if (srcPos + length > src.length || destPos + length > dest.length)
153 throw new IndexOutOfBoundsException();
154
155 for (int i = 0; i < length; i++)
156 {
157 dest[destPos + i] = src[srcPos + i];
158 }
159 }
160
161 private static void arrayCopy(float[] src, int srcPos, float[] dest, int destPos, int length)
162 {
163 if (srcPos + length > src.length || destPos + length > dest.length)
164 throw new IndexOutOfBoundsException();
165
166 for (int i = 0; i < length; i++)
167 {
168 dest[destPos + i] = src[srcPos + i];
169 }
170 }
171
172 private static void arrayCopy(char[] src, int srcPos, char[] dest, int destPos, int length)
173 {
174 if (srcPos + length > src.length || destPos + length > dest.length)
175 throw new IndexOutOfBoundsException();
176
177 for (int i = 0; i < length; i++)
178 {
179 dest[destPos + i] = src[srcPos + i];
180 }
181 }
182
183 private static void arrayCopy(byte[] src, int srcPos, byte[] dest, int destPos, int length)
184 {
185 if (srcPos + length > src.length || destPos + length > dest.length)
186 throw new IndexOutOfBoundsException();
187
188 for (int i = 0; i < length; i++)
189 {
190 dest[destPos + i] = src[srcPos + i];
191 }
192 }
193
194 private static void arrayCopy(short[] src, int srcPos, short[] dest, int destPos, int length)
195 {
196 if (srcPos + length > src.length || destPos + length > dest.length)
197 throw new IndexOutOfBoundsException();
198
199 for (int i = 0; i < length; i++)
200 {
201 dest[destPos + i] = src[srcPos + i];
202 }
203 }
204
205 private static void arrayCopy(long[] src, int srcPos, long[] dest, int destPos, int length)
206 {
207 if (srcPos + length > src.length || destPos + length > dest.length)
208 throw new IndexOutOfBoundsException();
209
210 for (int i = 0; i < length; i++)
211 {
212 dest[destPos + i] = src[srcPos + i];
213 }
214 }
215
216 private static void arrayCopy(double[] src, int srcPos, double[] dest, int destPos, int length)
217 {
218 if (srcPos + length > src.length || destPos + length > dest.length)
219 throw new IndexOutOfBoundsException();
220
221 for (int i = 0; i < length; i++)
222 {
223 dest[destPos + i] = src[srcPos + i];
224 }
225 }
226
227 /**
228 * Copies all of the elements in <code>list</code> to <code>array</code>.
229 * Similar to {@link List#toArray(Object[])} except this does not
230 * automatically expand the array size.
231 *
232 * @param src a list
233 * @param dest a non-primitive array
234 * @throws NullPointerException if <code>src</code> or <code>dest</code>
235 * is <code>null</code>
236 * @throws IndexOutOfBoundsException if <code>dest</code> is not large
237 * enough to contain all of the list elements.
238 * @throws ArrayStoreException if an element in <code>list</code> cannot
239 * not be copied to <code>dest</code> due to a type mismatch
240 */
241 public static Object[] toArray(List src, Object[] dest)
242 {
243 // necessary in web mode
244 if (src == null || dest == null)
245 throw new NullPointerException();
246
247 int size = src.size();
248 rangeCheck(0, dest.length, size - 1, false);
249
250 for (int i = 0; i < size; i++)
251 {
252 dest[i] = src.get(i);
253 }
254
255 return dest;
256 }
257
258 /**
259 * Tests two Strings for equality. Same as {@link String#equals(Object)}.
260 * Either argument may be <code>null</code>.
261 *
262 * @param a a String, or <code>null</code>
263 * @param b a String, or <code>null</code>
264 * @return <code>true</code> if <code>(a == b || a != null && a.equals(b))</code>
265 */
266 public static native boolean equals(String a, String b) /*-{
267 return a == b;
268 }-*/;
269 }