All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.htmlunit.corejs.javascript.Kit Maven / Gradle / Ivy

/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.htmlunit.corejs.javascript;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/** Collection of utilities */
public class Kit {
    public static Class classOrNull(String className) {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException ex) {
        } catch (SecurityException ex) {
        } catch (LinkageError ex) {
        } catch (IllegalArgumentException e) {
            // Can be thrown if name has characters that a class name
            // can not contain
        }
        return null;
    }

    /** Attempt to load the class of the given name. Note that the type parameter isn't checked. */
    public static Class classOrNull(ClassLoader loader, String className) {
        try {
            return loader.loadClass(className);
        } catch (ClassNotFoundException ex) {
        } catch (SecurityException ex) {
        } catch (LinkageError ex) {
        } catch (IllegalArgumentException e) {
            // Can be thrown if name has characters that a class name
            // can not contain
        }
        return null;
    }

    static Object newInstanceOrNull(Class cl) {
        try {
            return cl.getDeclaredConstructor().newInstance();
        } catch (SecurityException
                | LinkageError
                | InstantiationException
                | IllegalAccessException
                | NoSuchMethodException
                | InvocationTargetException x) {
        }
        return null;
    }

    /** Check that testClass is accessible from the given loader. */
    static boolean testIfCanLoadRhinoClasses(ClassLoader loader) {
        Class testClass = ScriptRuntime.ContextFactoryClass;
        Class x = Kit.classOrNull(loader, testClass.getName());
        if (x != testClass) {
            // The check covers the case when x == null =>
            // loader does not know about testClass or the case
            // when x != null && x != testClass =>
            // loader loads a class unrelated to testClass
            return false;
        }
        return true;
    }

    /**
     * If character c is a hexadecimal digit, return accumulator * 16 plus
     * corresponding number. Otherise return -1.
     */
    public static int xDigitToInt(int c, int accumulator) {
        check:
        {
            // Use 0..9 < A..Z < a..z
            if (c <= '9') {
                c -= '0';
                if (0 <= c) {
                    break check;
                }
            } else if (c <= 'F') {
                if ('A' <= c) {
                    c -= ('A' - 10);
                    break check;
                }
            } else if (c <= 'f') {
                if ('a' <= c) {
                    c -= ('a' - 10);
                    break check;
                }
            }
            return -1;
        }
        return (accumulator << 4) | c;
    }

    /**
     * Add listener to bag of listeners. The function does not modify bag and
     * return a new collection containing listener and all listeners from bag. Bag
     * without listeners always represented as the null value.
     *
     * 

Usage example: * *

     *     private volatile Object changeListeners;
     *
     *     public void addMyListener(PropertyChangeListener l)
     *     {
     *         synchronized (this) {
     *             changeListeners = Kit.addListener(changeListeners, l);
     *         }
     *     }
     *
     *     public void removeTextListener(PropertyChangeListener l)
     *     {
     *         synchronized (this) {
     *             changeListeners = Kit.removeListener(changeListeners, l);
     *         }
     *     }
     *
     *     public void fireChangeEvent(Object oldValue, Object newValue)
     *     {
     *     // Get immune local copy
     *         Object listeners = changeListeners;
     *         if (listeners != null) {
     *             PropertyChangeEvent e = new PropertyChangeEvent(
     *                 this, "someProperty" oldValue, newValue);
     *             for (int i = 0; ; ++i) {
     *                 Object l = Kit.getListener(listeners, i);
     *                 if (l == null)
     *                     break;
     *                 ((PropertyChangeListener)l).propertyChange(e);
     *             }
     *         }
     *     }
     * 
* * @param listener Listener to add to bag * @param bag Current collection of listeners. * @return A new bag containing all listeners from bag and listener. * @see #removeListener(Object bag, Object listener) * @see #getListener(Object bag, int index) */ public static Object addListener(Object bag, Object listener) { if (listener == null) throw new IllegalArgumentException(); if (listener instanceof Object[]) throw new IllegalArgumentException(); if (bag == null) { bag = listener; } else if (!(bag instanceof Object[])) { bag = new Object[] {bag, listener}; } else { Object[] array = (Object[]) bag; int L = array.length; // bag has at least 2 elements if it is array if (L < 2) throw new IllegalArgumentException(); Object[] tmp = new Object[L + 1]; System.arraycopy(array, 0, tmp, 0, L); tmp[L] = listener; bag = tmp; } return bag; } /** * Remove listener from bag of listeners. The function does not modify bag * and return a new collection containing all listeners from bag except listener. * If bag does not contain listener, the function returns bag. * *

For usage example, see {@link #addListener(Object bag, Object listener)}. * * @param listener Listener to remove from bag * @param bag Current collection of listeners. * @return A new bag containing all listeners from bag except listener. * @see #addListener(Object bag, Object listener) * @see #getListener(Object bag, int index) */ public static Object removeListener(Object bag, Object listener) { if (listener == null) throw new IllegalArgumentException(); if (listener instanceof Object[]) throw new IllegalArgumentException(); if (bag == listener) { bag = null; } else if (bag instanceof Object[]) { Object[] array = (Object[]) bag; int L = array.length; // bag has at least 2 elements if it is array if (L < 2) throw new IllegalArgumentException(); if (L == 2) { if (array[1] == listener) { bag = array[0]; } else if (array[0] == listener) { bag = array[1]; } } else { int i = L; do { --i; if (array[i] == listener) { Object[] tmp = new Object[L - 1]; System.arraycopy(array, 0, tmp, 0, i); System.arraycopy(array, i + 1, tmp, i, L - (i + 1)); bag = tmp; break; } } while (i != 0); } } return bag; } /** * Get listener at index position in bag or null if index equals to number * of listeners in bag. * *

For usage example, see {@link #addListener(Object bag, Object listener)}. * * @param bag Current collection of listeners. * @param index Index of the listener to access. * @return Listener at the given index or null. * @see #addListener(Object bag, Object listener) * @see #removeListener(Object bag, Object listener) */ public static Object getListener(Object bag, int index) { if (index == 0) { if (bag == null) return null; if (!(bag instanceof Object[])) return bag; Object[] array = (Object[]) bag; // bag has at least 2 elements if it is array if (array.length < 2) throw new IllegalArgumentException(); return array[0]; } else if (index == 1) { if (!(bag instanceof Object[])) { if (bag == null) throw new IllegalArgumentException(); return null; } Object[] array = (Object[]) bag; // the array access will check for index on its own return array[1]; } else { // bag has to array Object[] array = (Object[]) bag; int L = array.length; if (L < 2) throw new IllegalArgumentException(); if (index == L) return null; return array[index]; } } static Object initHash(Map h, Object key, Object initialValue) { synchronized (h) { Object current = h.get(key); if (current == null) { h.put(key, initialValue); } else { initialValue = current; } } return initialValue; } private static final class ComplexKey { private Object key1; private Object key2; private int hash; ComplexKey(Object key1, Object key2) { this.key1 = key1; this.key2 = key2; } @Override public boolean equals(Object anotherObj) { if (!(anotherObj instanceof ComplexKey)) return false; ComplexKey another = (ComplexKey) anotherObj; return key1.equals(another.key1) && key2.equals(another.key2); } @Override public int hashCode() { if (hash == 0) { hash = key1.hashCode() ^ key2.hashCode(); } return hash; } } public static Object makeHashKeyFromPair(Object key1, Object key2) { if (key1 == null) throw new IllegalArgumentException(); if (key2 == null) throw new IllegalArgumentException(); return new ComplexKey(key1, key2); } public static String readReader(Reader reader) throws IOException { try (BufferedReader in = new BufferedReader(reader)) { char[] cbuf = new char[1024]; StringBuilder sb = new StringBuilder(1024); int bytes_read; while ((bytes_read = in.read(cbuf, 0, 1024)) != -1) { sb.append(cbuf, 0, bytes_read); } return sb.toString(); } } public static byte[] readStream(InputStream is, int initialBufferCapacity) throws IOException { if (initialBufferCapacity <= 0) { throw new IllegalArgumentException( "Bad initialBufferCapacity: " + initialBufferCapacity); } byte[] buffer = new byte[initialBufferCapacity]; int cursor = 0; for (; ; ) { int n = is.read(buffer, cursor, buffer.length - cursor); if (n < 0) { break; } cursor += n; if (cursor == buffer.length) { int readahead = -1; if (cursor == initialBufferCapacity) { readahead = is.read(); if (readahead < 0) { // Check for EOS return buffer; } } byte[] tmp = new byte[buffer.length * 2]; System.arraycopy(buffer, 0, tmp, 0, cursor); buffer = tmp; if (readahead != -1) { buffer[cursor++] = (byte) readahead; readahead = -1; } } } if (cursor != buffer.length) { byte[] tmp = new byte[cursor]; System.arraycopy(buffer, 0, tmp, 0, cursor); buffer = tmp; } return buffer; } /** * Throws RuntimeException to indicate failed assertion. The function never returns and its * return type is RuntimeException only to be able to write throw Kit.codeBug() if * plain Kit.codeBug() triggers unreachable code error. */ public static RuntimeException codeBug() throws RuntimeException { RuntimeException ex = new IllegalStateException("FAILED ASSERTION"); // Print stack trace ASAP ex.printStackTrace(System.err); throw ex; } /** * Throws RuntimeException to indicate failed assertion. The function never returns and its * return type is RuntimeException only to be able to write throw Kit.codeBug() if * plain Kit.codeBug() triggers unreachable code error. */ public static RuntimeException codeBug(String msg) throws RuntimeException { msg = "FAILED ASSERTION: " + msg; RuntimeException ex = new IllegalStateException(msg); // Print stack trace ASAP ex.printStackTrace(System.err); throw ex; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy