|
1 /******************************************************************************* |
|
2 * Copyright (c) 2000, 2009 IBM Corporation and others. |
|
3 * All rights reserved. This program and the accompanying materials |
|
4 * are made available under the terms of the Eclipse Public License v1.0 |
|
5 * which accompanies this distribution, and is available at |
|
6 * http://www.eclipse.org/legal/epl-v10.html |
|
7 * |
|
8 * Contributors: |
|
9 * IBM Corporation - initial API and implementation |
|
10 * Nokia Corporation - Qt implementation |
|
11 *******************************************************************************/ |
|
12 package org.eclipse.swt.internal; |
|
13 |
|
14 |
|
15 import org.eclipse.swt.SWT; |
|
16 import java.io.*; |
|
17 import com.nokia.mj.impl.utils.ResourceLoader; |
|
18 //import java.util.zip.DeflaterOutputStream; |
|
19 |
|
20 /** |
|
21 * This class is a placeholder for utility methods commonly |
|
22 * used on J2SE platforms but not supported on some J2ME |
|
23 * profiles. |
|
24 * <p> |
|
25 * It is part of our effort to provide support for both J2SE |
|
26 * and J2ME platforms. |
|
27 * </p> |
|
28 * <p> |
|
29 * IMPORTANT: some of the methods have been modified from their |
|
30 * J2SE parents. Refer to the description of each method for |
|
31 * specific changes. |
|
32 * </p> |
|
33 * <ul> |
|
34 * <li>Exceptions thrown may differ since J2ME's set of |
|
35 * exceptions is a subset of J2SE's one. |
|
36 * </li> |
|
37 * <li>The range of the mathematic functions is subject to |
|
38 * change. |
|
39 * </li> |
|
40 * </ul> |
|
41 */ |
|
42 public final class Compatibility { |
|
43 |
|
44 /** |
|
45 * Returns the PI constant as a double. |
|
46 */ |
|
47 public static final double PI = (double)3.141592653589793; |
|
48 |
|
49 private static ResourceLoader iRes; |
|
50 |
|
51 /** |
|
52 * Sine table |
|
53 * <p> |
|
54 * Values represent sine for each degree between 0 and 90. Values have |
|
55 * been multiplied by 65536 and rounded. |
|
56 * </p> |
|
57 */ |
|
58 static int[] sineTable = { |
|
59 0, 1143, 2287, 3429, 4571, 5711, 6850, 7986, 9120, 10252, // 0 to 9 degrees |
|
60 11380, 12504, 13625, 14742, 15854, 16961, 18064, 19160, 20251, 21336, // 10 to 19 degrees |
|
61 22414, 23486, 24550, 25606, 26655, 27696, 28729, 29752, 30767, 31772, // 20 to 29 degrees |
|
62 32767, 33753, 34728, 35693, 36647, 37589, 38521, 39440, 40347, 41243, // 30 to 39 degrees |
|
63 42125, 42995, 43852, 44695, 45525, 46340, 47142, 47929, 48702, 49460, // 40 to 49 degrees |
|
64 50203, 50931, 51643, 52339, 53019, 53683, 54331, 54963, 55577, 56175, // 50 to 59 degrees |
|
65 56755, 57319, 57864, 58393, 58903, 59395, 59870, 60326, 60763, 61183, // 60 to 69 degrees |
|
66 61583, 61965, 62328, 62672, 62997, 63302, 63589, 63856, 64103, 64331, // 70 to 79 degrees |
|
67 64540, 64729, 64898, 65047, 65176, 65286, 65376, 65446, 65496, 65526, // 80 to 89 degrees |
|
68 65536 }; // 90 degrees |
|
69 |
|
70 private static final String CLDC_COMPATIBILITY_DELEGATE = "org.eclipse.swt.internal.CLDCCompatibilityDelegate"; |
|
71 private static final String CDC_COMPATIBILITY_DELEGATE = "org.eclipse.swt.internal.CDCCompatibilityDelegate"; |
|
72 |
|
73 private static CompatibilityDelegate fDelegate; |
|
74 |
|
75 /** |
|
76 * Tests whether the application can read the file denoted by the path. |
|
77 * |
|
78 * @param path the path string |
|
79 * @return true if and only if the file specified by this path exists and can be opened by the application; false otherwise |
|
80 * @exception SecurityException |
|
81 */ |
|
82 public static boolean canOpenFile(String path) throws SecurityException { |
|
83 return getDelegate().canOpenFile(path); |
|
84 } |
|
85 |
|
86 private static CompatibilityDelegate getDelegate() { |
|
87 if(fDelegate == null) { |
|
88 Class clazz; |
|
89 try { |
|
90 clazz = Class.forName(CLDC_COMPATIBILITY_DELEGATE); |
|
91 fDelegate = (CompatibilityDelegate) clazz.newInstance(); |
|
92 } catch(Exception e) { |
|
93 |
|
94 } |
|
95 if(fDelegate == null) { |
|
96 try { |
|
97 clazz = Class.forName(CDC_COMPATIBILITY_DELEGATE); |
|
98 fDelegate = (CompatibilityDelegate) clazz.newInstance(); |
|
99 } catch(Exception e) { |
|
100 throw new RuntimeException("Can not instantiate Compatibility Delegate"); |
|
101 } |
|
102 } |
|
103 } |
|
104 return fDelegate; |
|
105 } |
|
106 |
|
107 /** |
|
108 * Answers the length of the side adjacent to the given angle |
|
109 * of a right triangle. In other words, it returns the integer |
|
110 * conversion of length * cos (angle). |
|
111 * <p> |
|
112 * IMPORTANT: the j2me version has an additional restriction on |
|
113 * the argument. length must be between -32767 and 32767 (inclusive). |
|
114 * </p> |
|
115 * |
|
116 * @param angle the angle in degrees |
|
117 * @param length the length of the triangle's hypotenuse |
|
118 * @return the integer conversion of length * cos (angle) |
|
119 */ |
|
120 public static int cos(int angle, int length) { |
|
121 return sin(90 - angle, length); |
|
122 } |
|
123 |
|
124 /** |
|
125 * Answers the length of the side opposite to the given angle |
|
126 * of a right triangle. In other words, it returns the integer |
|
127 * conversion of length * sin (angle). |
|
128 * <p> |
|
129 * IMPORTANT: the j2me version has an additional restriction on |
|
130 * the argument. length must be between -32767 and 32767 (inclusive). |
|
131 * </p> |
|
132 * |
|
133 * @param angle the angle in degrees |
|
134 * @param length the length of the triangle's hypotenuse |
|
135 * @return the integer conversion of length * sin (angle) |
|
136 */ |
|
137 public static int sin(int angle, int length) { |
|
138 if (length < -32767 || length > 32767) { |
|
139 SWT.error(SWT.ERROR_INVALID_RANGE); |
|
140 } |
|
141 if (angle < 0 || angle >= 360) { |
|
142 angle = angle % 360; |
|
143 if (angle < 0) angle += 360; |
|
144 } |
|
145 |
|
146 int sineValue; |
|
147 if (angle >= 0 && angle < 90) sineValue = sineTable[angle]; |
|
148 else if (angle >= 90 && angle < 180) sineValue = sineTable[180 - angle]; |
|
149 else if (angle >= 180 && angle < 270) sineValue = 0 - sineTable[angle - 180]; |
|
150 else { |
|
151 // angle >= 270 && angle < 360 |
|
152 sineValue = 0 - sineTable[360 - angle]; |
|
153 } |
|
154 |
|
155 return (sineValue * length) >> 16; |
|
156 } |
|
157 |
|
158 /** |
|
159 * Answers the most negative (i.e. closest to negative infinity) |
|
160 * integer value which is greater than the number obtained by dividing |
|
161 * the first argument p by the second argument q. |
|
162 * |
|
163 * @param p numerator |
|
164 * @param q denominator (must be different from zero) |
|
165 * @return the ceiling of the rational number p / q. |
|
166 */ |
|
167 public static int ceil(int p, int q) { |
|
168 int res = p / q; |
|
169 if ((p % q == 0) || |
|
170 (res < 0) || |
|
171 ((res == 0) && ((p < 0 && q > 0) || (p > 0 && q < 0)))) |
|
172 return res; |
|
173 else |
|
174 return res + 1; |
|
175 } |
|
176 |
|
177 /** |
|
178 * Answers the most positive (i.e. closest to positive infinity) |
|
179 * integer value which is less than the number obtained by dividing |
|
180 * the first argument p by the second argument q. |
|
181 * |
|
182 * @param p numerator |
|
183 * @param q denominator (must be different from zero) |
|
184 * @return the floor of the rational number p / q. |
|
185 */ |
|
186 public static int floor(int p, int q) { |
|
187 int res = p / q; |
|
188 if ((p % q == 0) || |
|
189 (res > 0) || |
|
190 ((res == 0) && ((p > 0 && q > 0) || (p < 0 && q < 0)))) |
|
191 return res; |
|
192 else |
|
193 return res - 1; |
|
194 } |
|
195 |
|
196 /** |
|
197 * Answers the result of rounding to the closest integer the number obtained |
|
198 * by dividing the first argument p by the second argument q. |
|
199 * <p> |
|
200 * IMPORTANT: the j2me version has an additional restriction on |
|
201 * the arguments. p must be within the range 0 - 32767 (inclusive). |
|
202 * q must be within the range 1 - 32767 (inclusive). |
|
203 * </p> |
|
204 * |
|
205 * @param p numerator |
|
206 * @param q denominator (must be different from zero) |
|
207 * @return the closest integer to the rational number p / q |
|
208 */ |
|
209 public static int round(int p, int q) { |
|
210 if (p < 0 || p > 32767 || q < 1 || q > 32767) { |
|
211 SWT.error(SWT.ERROR_INVALID_RANGE); |
|
212 } |
|
213 return (2 * p + q) / (2 * q); |
|
214 } |
|
215 |
|
216 /** |
|
217 * Returns 2 raised to the power of the argument. |
|
218 * |
|
219 * @param n an int value between 0 and 30 (inclusive) |
|
220 * @return 2 raised to the power of the argument |
|
221 * |
|
222 * @exception IllegalArgumentException <ul> |
|
223 * <li>ERROR_INVALID_RANGE - if the argument is not between 0 and 30 (inclusive)</li> |
|
224 * </ul> |
|
225 */ |
|
226 public static int pow2(int n) { |
|
227 if (n >= 1 && n <= 30) |
|
228 return 2 << (n - 1); |
|
229 else if (n != 0) { |
|
230 SWT.error(SWT.ERROR_INVALID_RANGE); |
|
231 } |
|
232 return 1; |
|
233 } |
|
234 |
|
235 /** |
|
236 * Create an DeflaterOutputStream if such things are supported. |
|
237 * |
|
238 * @param stream the output stream |
|
239 * @return a deflater stream or <code>null</code> |
|
240 * @exception IOException |
|
241 * |
|
242 * @since 3.4 |
|
243 */ |
|
244 public static OutputStream newDeflaterOutputStream(OutputStream stream) throws IOException { |
|
245 return null; |
|
246 } |
|
247 |
|
248 /** |
|
249 * Open a file if such things are supported. |
|
250 * |
|
251 * @param filename the name of the file to open |
|
252 * @return a stream on the file if it could be opened. |
|
253 */ |
|
254 public static InputStream newFileInputStream(String filename) throws IOException { |
|
255 return getDelegate().getInputStreamFromFile(filename); |
|
256 } |
|
257 |
|
258 /** |
|
259 * Open a file if such things are supported. |
|
260 * |
|
261 * @param filename the name of the file to open |
|
262 * @return a stream on the file if it could be opened. |
|
263 */ |
|
264 public static OutputStream newFileOutputStream(String filename) throws IOException { |
|
265 return getDelegate().getOutStreamFromFile(filename); |
|
266 } |
|
267 |
|
268 /** |
|
269 * Create an InflaterInputStream if such things are supported. |
|
270 * |
|
271 * @param stream the input stream |
|
272 * @return a inflater stream or <code>null</code> |
|
273 * @exception IOException |
|
274 * |
|
275 * @since 3.3 |
|
276 */ |
|
277 public static InputStream newInflaterInputStream(InputStream stream) throws IOException { |
|
278 return null; |
|
279 } |
|
280 |
|
281 /** |
|
282 * Answers whether the character is a letter. |
|
283 * |
|
284 * @param c the character |
|
285 * @return true when the character is a letter |
|
286 */ |
|
287 public static boolean isLetter(char c) { |
|
288 return (Character.isUpperCase(c)) || (Character.isLowerCase(c)); |
|
289 } |
|
290 |
|
291 /** |
|
292 * Answers whether the character is a letter or a digit. |
|
293 * |
|
294 * @param c the character |
|
295 * @return true when the character is a letter or a digit |
|
296 */ |
|
297 public static boolean isLetterOrDigit(char c) { |
|
298 return isLetter(c) || Character.isDigit(c); |
|
299 } |
|
300 |
|
301 /** |
|
302 * Answers whether the character is a Unicode space character. |
|
303 * |
|
304 * @param c the character |
|
305 * @return true when the character is a Unicode space character |
|
306 */ |
|
307 public static boolean isSpaceChar(char c) { |
|
308 return c == ' '; |
|
309 } |
|
310 |
|
311 /** |
|
312 * Answers whether the character is whitespace character. |
|
313 * |
|
314 * @param c the character |
|
315 * @return true when the character is a whitespace character |
|
316 */ |
|
317 public static boolean isWhitespace(char c) { |
|
318 // Optimized case for ASCII |
|
319 if ((c >= 0x1c && c <= 0x20) || (c >= 0x9 && c <= 0xd)) |
|
320 return true; |
|
321 return false; |
|
322 } |
|
323 |
|
324 /** |
|
325 * Execute a program in a separate platform process if the |
|
326 * underlying platform support this. |
|
327 * <p> |
|
328 * The new process inherits the environment of the caller. |
|
329 * </p> |
|
330 * |
|
331 * @param program the name of the program to execute |
|
332 * |
|
333 * @exception IOException |
|
334 * if the program cannot be executed |
|
335 * @exception SecurityException |
|
336 * if the current SecurityManager disallows program execution |
|
337 */ |
|
338 public static void exec(String prog) throws java.io.IOException { |
|
339 throw new IOException(); |
|
340 } |
|
341 |
|
342 /** |
|
343 * Answers whether the indicated file exists or not. |
|
344 * |
|
345 * @param parent the file's parent directory |
|
346 * @param child the file's name |
|
347 * @return true if the file exists |
|
348 */ |
|
349 public static boolean fileExists(String parent, String child) { |
|
350 return false; |
|
351 } |
|
352 |
|
353 /** |
|
354 * Execute progArray[0] in a separate platform process if the |
|
355 * underlying platform support this. |
|
356 * <p> |
|
357 * The new process inherits the environment of the caller. |
|
358 * <p> |
|
359 * |
|
360 * @param progArray array containing the program to execute and its arguments |
|
361 * |
|
362 * @exception IOException |
|
363 * if the program cannot be executed |
|
364 * @exception SecurityException |
|
365 * if the current SecurityManager disallows program execution |
|
366 */ |
|
367 public static void exec(String[] progArray) throws java.io.IOException{ |
|
368 throw new IOException(); |
|
369 } |
|
370 |
|
371 /** |
|
372 * Returns the NLS'ed message for the given argument. This is only being |
|
373 * called from SWT. |
|
374 * |
|
375 * @param key the key to look up |
|
376 * @return the message for the given key |
|
377 * |
|
378 * @see SWT#getMessage |
|
379 */ |
|
380 public static String getMessage(String key) { |
|
381 |
|
382 if (key == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
|
383 |
|
384 if(key.equals("ok")){ |
|
385 iRes = ResourceLoader.getInstance("eswtcore", "qtn_eswt_softkey_"); |
|
386 return iRes.format(key).toString(); |
|
387 } |
|
388 |
|
389 if(key.equals("cancel")){ |
|
390 iRes = ResourceLoader.getInstance("eswtcore", "qtn_eswt_softkey_"); |
|
391 return iRes.format(key).toString(); |
|
392 } |
|
393 |
|
394 if(key.equals("fetch_url")){ |
|
395 iRes = ResourceLoader.getInstance("eswtmobile", "qtn_eswt_option_"); |
|
396 return iRes.format(key).toString(); |
|
397 } |
|
398 |
|
399 if(key.equals("fetch_email")){ |
|
400 iRes = ResourceLoader.getInstance("eswtmobile", "qtn_eswt_option_pb_"); |
|
401 return iRes.format(key).toString(); |
|
402 } |
|
403 |
|
404 if(key.equals("dialog_title")){ |
|
405 iRes = ResourceLoader.getInstance("eswtmobile", "qtn_eswt_favorites_"); |
|
406 return iRes.format(key).toString(); |
|
407 } |
|
408 |
|
409 return key; |
|
410 } |
|
411 |
|
412 public static String getMessage(String key, Object[] args) { |
|
413 if (key == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
|
414 if (key.equals("SWT_Download_File")) return "Download: "+args[0]; //$NON-NLS-1$ |
|
415 if (key.equals("SWT_Download_Location")) return "Saving "+args[0]+" from "+args[1]; //$NON-NLS-1$ |
|
416 if (key.equals("SWT_Download_Status")) return "Download: "+args[0]+" KB of "+args[1]+" KB"; //$NON-NLS-1$ |
|
417 return key; |
|
418 } |
|
419 |
|
420 /** |
|
421 * Interrupt the current thread. |
|
422 * <p> |
|
423 * Note that this is not available on CLDC. |
|
424 * </p> |
|
425 */ |
|
426 public static void interrupt() { |
|
427 } |
|
428 |
|
429 /** |
|
430 * Compares two instances of class String ignoring the case of the |
|
431 * characters and answers if they are equal. |
|
432 * |
|
433 * @param s1 string |
|
434 * @param s2 string |
|
435 * @return true if the two instances of class String are equal |
|
436 */ |
|
437 public static boolean equalsIgnoreCase(String s1, String s2) { |
|
438 if (s1 == s2) return true; |
|
439 if (s2 == null || s1.length() != s2.length()) return false; |
|
440 |
|
441 char[] cArray1 = s1.toCharArray(); |
|
442 char[] cArray2 = s2.toCharArray(); |
|
443 int length = s1.length(); |
|
444 char c1, c2; |
|
445 |
|
446 for (int index = 0; index < length; index++) { |
|
447 c1 = cArray1[index]; |
|
448 c2 = cArray2[index]; |
|
449 if (c1 != c2 && |
|
450 Character.toUpperCase(c1) != Character.toUpperCase(c2) && |
|
451 Character.toLowerCase(c1) != Character.toLowerCase(c2)) { |
|
452 return false; |
|
453 } |
|
454 } |
|
455 return true; |
|
456 } |
|
457 |
|
458 } |