~davewalker/etherpad/ubuntu-unlimited-max-users-and-revisions

« back to all changes in this revision

Viewing changes to infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java

  • Committer: James Page
  • Date: 2011-04-13 08:00:43 UTC
  • Revision ID: james.page@canonical.com-20110413080043-eee2nq7y1v7cv2mp
* Refactoring to use native Ubuntu Java libraries. 
* debian/control:
  - use openjdk instead of sun's java
  - update maintainer
* debian/etherpad.init.orig, debian/etherpad.upstart:
  - move the init script out of the way
  - create a basic upstart script
  - note that the open office document conversion daemon was dropped
    from the upstart configuration; if this behavior is desired, please
    create a separate upstart job for it
* debian/rules:
  - just use basic dh_installinit, as it will pick up the new upstart job
* New release
* Changed maintainer to Packaging
* Fixed installation scripts
* Initial Release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 
2
 *
 
3
 * ***** BEGIN LICENSE BLOCK *****
 
4
 * Version: MPL 1.1/GPL 2.0
 
5
 *
 
6
 * The contents of this file are subject to the Mozilla Public License Version
 
7
 * 1.1 (the "License"); you may not use this file except in compliance with
 
8
 * the License. You may obtain a copy of the License at
 
9
 * http://www.mozilla.org/MPL/
 
10
 *
 
11
 * Software distributed under the License is distributed on an "AS IS" basis,
 
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
13
 * for the specific language governing rights and limitations under the
 
14
 * License.
 
15
 *
 
16
 * The Original Code is Rhino code, released
 
17
 * May 6, 1999.
 
18
 *
 
19
 * The Initial Developer of the Original Code is
 
20
 * Netscape Communications Corporation.
 
21
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 
22
 * the Initial Developer. All Rights Reserved.
 
23
 *
 
24
 * Contributor(s):
 
25
 *   Igor Bukanov, igor@fastmail.fm
 
26
 *
 
27
 * Alternatively, the contents of this file may be used under the terms of
 
28
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 
29
 * case the provisions of the GPL are applicable instead of those above. If
 
30
 * you wish to allow use of your version of this file only under the terms of
 
31
 * the GPL and not to allow others to use your version of this file under the
 
32
 * MPL, indicate your decision by deleting the provisions above and replacing
 
33
 * them with the notice and other provisions required by the GPL. If you do
 
34
 * not delete the provisions above, a recipient may use your version of this
 
35
 * file under either the MPL or the GPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
package org.mozilla.javascript;
 
40
 
 
41
import java.io.IOException;
 
42
import java.io.InputStream;
 
43
import java.io.Reader;
 
44
import java.lang.reflect.Method;
 
45
import java.util.Hashtable;
 
46
 
 
47
/**
 
48
 * Collection of utilities
 
49
 */
 
50
 
 
51
public class Kit
 
52
{
 
53
    /**
 
54
     * Reflection of Throwable.initCause(Throwable) from JDK 1.4
 
55
     * or nul if it is not available.
 
56
     */
 
57
    private static Method Throwable_initCause = null;
 
58
 
 
59
    static {
 
60
        // Are we running on a JDK 1.4 or later system?
 
61
        try {
 
62
            Class ThrowableClass = Kit.classOrNull("java.lang.Throwable");
 
63
            Class[] signature = { ThrowableClass };
 
64
            Throwable_initCause
 
65
                = ThrowableClass.getMethod("initCause", signature);
 
66
        } catch (Exception ex) {
 
67
            // Assume any exceptions means the method does not exist.
 
68
        }
 
69
    }
 
70
 
 
71
    public static Class classOrNull(String className)
 
72
    {
 
73
        try {
 
74
            return Class.forName(className);
 
75
        } catch  (ClassNotFoundException ex) {
 
76
        } catch  (SecurityException ex) {
 
77
        } catch  (LinkageError ex) {
 
78
        } catch (IllegalArgumentException e) {
 
79
            // Can be thrown if name has characters that a class name
 
80
            // can not contain
 
81
        }
 
82
        return null;
 
83
    }
 
84
 
 
85
    public static Class classOrNull(ClassLoader loader, String className)
 
86
    {
 
87
        try {
 
88
            return loader.loadClass(className);
 
89
        } catch (ClassNotFoundException ex) {
 
90
        } catch (SecurityException ex) {
 
91
        } catch  (LinkageError ex) {
 
92
        } catch (IllegalArgumentException e) {
 
93
            // Can be thrown if name has characters that a class name
 
94
            // can not contain
 
95
        }
 
96
        return null;
 
97
    }
 
98
 
 
99
    static Object newInstanceOrNull(Class cl)
 
100
    {
 
101
        try {
 
102
            return cl.newInstance();
 
103
        } catch (SecurityException x) {
 
104
        } catch  (LinkageError ex) {
 
105
        } catch (InstantiationException x) {
 
106
        } catch (IllegalAccessException x) {
 
107
        }
 
108
        return null;
 
109
    }
 
110
 
 
111
    /**
 
112
     * Check that testClass is accesible from the given loader.
 
113
     */
 
114
    static boolean testIfCanLoadRhinoClasses(ClassLoader loader)
 
115
    {
 
116
        Class testClass = ScriptRuntime.ContextFactoryClass;
 
117
        Class x = Kit.classOrNull(loader, testClass.getName());
 
118
        if (x != testClass) {
 
119
            // The check covers the case when x == null =>
 
120
            // loader does not know about testClass or the case
 
121
            // when x != null && x != testClass =>
 
122
            // loader loads a class unrelated to testClass
 
123
            return false;
 
124
        }
 
125
        return true;
 
126
    }
 
127
 
 
128
    /**
 
129
     * If initCause methods exists in Throwable, call
 
130
     * <tt>ex.initCause(cause)</tt> or otherwise do nothing.
 
131
     * @return The <tt>ex</tt> argument.
 
132
     */
 
133
    public static RuntimeException initCause(RuntimeException ex,
 
134
                                             Throwable cause)
 
135
    {
 
136
        if (Throwable_initCause != null) {
 
137
            Object[] args = { cause };
 
138
            try {
 
139
                Throwable_initCause.invoke(ex, args);
 
140
            } catch (Exception e) {
 
141
                // Ignore any exceptions
 
142
            }
 
143
        }
 
144
        return ex;
 
145
    }
 
146
 
 
147
    /**
 
148
     * Split string into array of strings using semicolon as string terminator
 
149
     * (; after the last string is required).
 
150
     */
 
151
    public static String[] semicolonSplit(String s)
 
152
    {
 
153
        String[] array = null;
 
154
        for (;;) {
 
155
            // loop 2 times: first to count semicolons and then to fill array
 
156
            int count = 0;
 
157
            int cursor = 0;
 
158
            for (;;) {
 
159
                int next = s.indexOf(';', cursor);
 
160
                if (next < 0) {
 
161
                    break;
 
162
                }
 
163
                if (array != null) {
 
164
                    array[count] = s.substring(cursor, next);
 
165
                }
 
166
                ++count;
 
167
                cursor = next + 1;
 
168
            }
 
169
            // after the last semicolon
 
170
            if (array == null) {
 
171
                // array size counting state:
 
172
                // check for required terminating ';'
 
173
                if (cursor != s.length())
 
174
                    throw new IllegalArgumentException();
 
175
                array = new String[count];
 
176
            } else {
 
177
                // array filling state: stop the loop
 
178
                break;
 
179
            }
 
180
        }
 
181
        return array;
 
182
    }
 
183
 
 
184
    /**
 
185
     * If character <tt>c</tt> is a hexadecimal digit, return
 
186
     * <tt>accumulator</tt> * 16 plus corresponding
 
187
     * number. Otherise return -1.
 
188
     */
 
189
    public static int xDigitToInt(int c, int accumulator)
 
190
    {
 
191
        check: {
 
192
            // Use 0..9 < A..Z < a..z
 
193
            if (c <= '9') {
 
194
                c -= '0';
 
195
                if (0 <= c) { break check; }
 
196
            } else if (c <= 'F') {
 
197
                if ('A' <= c) {
 
198
                    c -= ('A' - 10);
 
199
                    break check;
 
200
                }
 
201
            } else if (c <= 'f') {
 
202
                if ('a' <= c) {
 
203
                    c -= ('a' - 10);
 
204
                    break check;
 
205
                }
 
206
            }
 
207
            return -1;
 
208
        }
 
209
        return (accumulator << 4) | c;
 
210
    }
 
211
 
 
212
    /**
 
213
     * Add <i>listener</i> to <i>bag</i> of listeners.
 
214
     * The function does not modify <i>bag</i> and return a new collection
 
215
     * containing <i>listener</i> and all listeners from <i>bag</i>.
 
216
     * Bag without listeners always represented as the null value.
 
217
     * <p>
 
218
     * Usage example:
 
219
     * <pre>
 
220
     *     private volatile Object changeListeners;
 
221
     *
 
222
     *     public void addMyListener(PropertyChangeListener l)
 
223
     *     {
 
224
     *         synchronized (this) {
 
225
     *             changeListeners = Kit.addListener(changeListeners, l);
 
226
     *         }
 
227
     *     }
 
228
     *
 
229
     *     public void removeTextListener(PropertyChangeListener l)
 
230
     *     {
 
231
     *         synchronized (this) {
 
232
     *             changeListeners = Kit.removeListener(changeListeners, l);
 
233
     *         }
 
234
     *     }
 
235
     *
 
236
     *     public void fireChangeEvent(Object oldValue, Object newValue)
 
237
     *     {
 
238
     *     // Get immune local copy
 
239
     *         Object listeners = changeListeners;
 
240
     *         if (listeners != null) {
 
241
     *             PropertyChangeEvent e = new PropertyChangeEvent(
 
242
     *                 this, "someProperty" oldValue, newValue);
 
243
     *             for (int i = 0; ; ++i) {
 
244
     *                 Object l = Kit.getListener(listeners, i);
 
245
     *                 if (l == null)
 
246
     *                     break;
 
247
     *                 ((PropertyChangeListener)l).propertyChange(e);
 
248
     *             }
 
249
     *         }
 
250
     *     }
 
251
     * </pre>
 
252
     *
 
253
     * @param listener Listener to add to <i>bag</i>
 
254
     * @param bag Current collection of listeners.
 
255
     * @return A new bag containing all listeners from <i>bag</i> and
 
256
     *          <i>listener</i>.
 
257
     * @see #removeListener(Object bag, Object listener)
 
258
     * @see #getListener(Object bag, int index)
 
259
     */
 
260
    public static Object addListener(Object bag, Object listener)
 
261
    {
 
262
        if (listener == null) throw new IllegalArgumentException();
 
263
        if (listener instanceof Object[]) throw new IllegalArgumentException();
 
264
 
 
265
        if (bag == null) {
 
266
            bag = listener;
 
267
        } else if (!(bag instanceof Object[])) {
 
268
            bag = new Object[] { bag, listener };
 
269
        } else {
 
270
            Object[] array = (Object[])bag;
 
271
            int L = array.length;
 
272
            // bag has at least 2 elements if it is array
 
273
            if (L < 2) throw new IllegalArgumentException();
 
274
            Object[] tmp = new Object[L + 1];
 
275
            System.arraycopy(array, 0, tmp, 0, L);
 
276
            tmp[L] = listener;
 
277
            bag = tmp;
 
278
        }
 
279
 
 
280
        return bag;
 
281
    }
 
282
 
 
283
    /**
 
284
     * Remove <i>listener</i> from <i>bag</i> of listeners.
 
285
     * The function does not modify <i>bag</i> and return a new collection
 
286
     * containing all listeners from <i>bag</i> except <i>listener</i>.
 
287
     * If <i>bag</i> does not contain <i>listener</i>, the function returns
 
288
     * <i>bag</i>.
 
289
     * <p>
 
290
     * For usage example, see {@link #addListener(Object bag, Object listener)}.
 
291
     *
 
292
     * @param listener Listener to remove from <i>bag</i>
 
293
     * @param bag Current collection of listeners.
 
294
     * @return A new bag containing all listeners from <i>bag</i> except
 
295
     *          <i>listener</i>.
 
296
     * @see #addListener(Object bag, Object listener)
 
297
     * @see #getListener(Object bag, int index)
 
298
     */
 
299
    public static Object removeListener(Object bag, Object listener)
 
300
    {
 
301
        if (listener == null) throw new IllegalArgumentException();
 
302
        if (listener instanceof Object[]) throw new IllegalArgumentException();
 
303
 
 
304
        if (bag == listener) {
 
305
            bag = null;
 
306
        } else if (bag instanceof Object[]) {
 
307
            Object[] array = (Object[])bag;
 
308
            int L = array.length;
 
309
            // bag has at least 2 elements if it is array
 
310
            if (L < 2) throw new IllegalArgumentException();
 
311
            if (L == 2) {
 
312
                if (array[1] == listener) {
 
313
                    bag = array[0];
 
314
                } else if (array[0] == listener) {
 
315
                    bag = array[1];
 
316
                }
 
317
            } else {
 
318
                int i = L;
 
319
                do {
 
320
                    --i;
 
321
                    if (array[i] == listener) {
 
322
                        Object[] tmp = new Object[L - 1];
 
323
                        System.arraycopy(array, 0, tmp, 0, i);
 
324
                        System.arraycopy(array, i + 1, tmp, i, L - (i + 1));
 
325
                        bag = tmp;
 
326
                        break;
 
327
                    }
 
328
                } while (i != 0);
 
329
            }
 
330
        }
 
331
 
 
332
        return bag;
 
333
    }
 
334
 
 
335
    /**
 
336
     * Get listener at <i>index</i> position in <i>bag</i> or null if
 
337
     * <i>index</i> equals to number of listeners in <i>bag</i>.
 
338
     * <p>
 
339
     * For usage example, see {@link #addListener(Object bag, Object listener)}.
 
340
     *
 
341
     * @param bag Current collection of listeners.
 
342
     * @param index Index of the listener to access.
 
343
     * @return Listener at the given index or null.
 
344
     * @see #addListener(Object bag, Object listener)
 
345
     * @see #removeListener(Object bag, Object listener)
 
346
     */
 
347
    public static Object getListener(Object bag, int index)
 
348
    {
 
349
        if (index == 0) {
 
350
            if (bag == null)
 
351
                return null;
 
352
            if (!(bag instanceof Object[]))
 
353
                return bag;
 
354
            Object[] array = (Object[])bag;
 
355
            // bag has at least 2 elements if it is array
 
356
            if (array.length < 2) throw new IllegalArgumentException();
 
357
            return array[0];
 
358
        } else if (index == 1) {
 
359
            if (!(bag instanceof Object[])) {
 
360
                if (bag == null) throw new IllegalArgumentException();
 
361
                return null;
 
362
            }
 
363
            Object[] array = (Object[])bag;
 
364
            // the array access will check for index on its own
 
365
            return array[1];
 
366
        } else {
 
367
            // bag has to array
 
368
            Object[] array = (Object[])bag;
 
369
            int L = array.length;
 
370
            if (L < 2) throw new IllegalArgumentException();
 
371
            if (index == L)
 
372
                return null;
 
373
            return array[index];
 
374
        }
 
375
    }
 
376
 
 
377
    static Object initHash(Hashtable h, Object key, Object initialValue)
 
378
    {
 
379
        synchronized (h) {
 
380
            Object current = h.get(key);
 
381
            if (current == null) {
 
382
                h.put(key, initialValue);
 
383
            } else {
 
384
                initialValue = current;
 
385
            }
 
386
        }
 
387
        return initialValue;
 
388
    }
 
389
 
 
390
    private final static class ComplexKey
 
391
    {
 
392
        private Object key1;
 
393
        private Object key2;
 
394
        private int hash;
 
395
 
 
396
        ComplexKey(Object key1, Object key2)
 
397
        {
 
398
            this.key1 = key1;
 
399
            this.key2 = key2;
 
400
        }
 
401
 
 
402
        public boolean equals(Object anotherObj)
 
403
        {
 
404
            if (!(anotherObj instanceof ComplexKey))
 
405
                return false;
 
406
            ComplexKey another = (ComplexKey)anotherObj;
 
407
            return key1.equals(another.key1) && key2.equals(another.key2);
 
408
        }
 
409
 
 
410
        public int hashCode()
 
411
        {
 
412
            if (hash == 0) {
 
413
                hash = key1.hashCode() ^ key2.hashCode();
 
414
            }
 
415
            return hash;
 
416
        }
 
417
    }
 
418
 
 
419
    public static Object makeHashKeyFromPair(Object key1, Object key2)
 
420
    {
 
421
        if (key1 == null) throw new IllegalArgumentException();
 
422
        if (key2 == null) throw new IllegalArgumentException();
 
423
        return new ComplexKey(key1, key2);
 
424
    }
 
425
 
 
426
    public static String readReader(Reader r)
 
427
        throws IOException
 
428
    {
 
429
        char[] buffer = new char[512];
 
430
        int cursor = 0;
 
431
        for (;;) {
 
432
            int n = r.read(buffer, cursor, buffer.length - cursor);
 
433
            if (n < 0) { break; }
 
434
            cursor += n;
 
435
            if (cursor == buffer.length) {
 
436
                char[] tmp = new char[buffer.length * 2];
 
437
                System.arraycopy(buffer, 0, tmp, 0, cursor);
 
438
                buffer = tmp;
 
439
            }
 
440
        }
 
441
        return new String(buffer, 0, cursor);
 
442
    }
 
443
 
 
444
    public static byte[] readStream(InputStream is, int initialBufferCapacity)
 
445
        throws IOException
 
446
    {
 
447
        if (initialBufferCapacity <= 0) {
 
448
            throw new IllegalArgumentException(
 
449
                "Bad initialBufferCapacity: "+initialBufferCapacity);
 
450
        }
 
451
        byte[] buffer = new byte[initialBufferCapacity];
 
452
        int cursor = 0;
 
453
        for (;;) {
 
454
            int n = is.read(buffer, cursor, buffer.length - cursor);
 
455
            if (n < 0) { break; }
 
456
            cursor += n;
 
457
            if (cursor == buffer.length) {
 
458
                byte[] tmp = new byte[buffer.length * 2];
 
459
                System.arraycopy(buffer, 0, tmp, 0, cursor);
 
460
                buffer = tmp;
 
461
            }
 
462
        }
 
463
        if (cursor != buffer.length) {
 
464
            byte[] tmp = new byte[cursor];
 
465
            System.arraycopy(buffer, 0, tmp, 0, cursor);
 
466
            buffer = tmp;
 
467
        }
 
468
        return buffer;
 
469
    }
 
470
 
 
471
    /**
 
472
     * Throws RuntimeException to indicate failed assertion.
 
473
     * The function never returns and its return type is RuntimeException
 
474
     * only to be able to write <tt>throw Kit.codeBug()</tt> if plain
 
475
     * <tt>Kit.codeBug()</tt> triggers unreachable code error.
 
476
     */
 
477
    public static RuntimeException codeBug()
 
478
        throws RuntimeException
 
479
    {
 
480
        RuntimeException ex = new IllegalStateException("FAILED ASSERTION");
 
481
        // Print stack trace ASAP
 
482
        ex.printStackTrace(System.err);
 
483
        throw ex;
 
484
    }
 
485
}
 
486