diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java')
-rw-r--r-- | bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java | 759 |
1 files changed, 0 insertions, 759 deletions
diff --git a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java b/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java deleted file mode 100644 index fad662590..000000000 --- a/bundles/org.eclipse.equinox.ds/src/org/eclipse/equinox/internal/util/io/ExternalizableDictionary.java +++ /dev/null @@ -1,759 +0,0 @@ -/******************************************************************************* - * Copyright (c) 1997, 2008 by ProSyst Software GmbH - * http://www.prosyst.com - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * ProSyst Software GmbH - initial API and implementation - *******************************************************************************/ -package org.eclipse.equinox.internal.util.io; - -import java.io.*; -import java.lang.reflect.Array; -import java.util.*; - -/** - * This class implements a hashtable, which serves the needs of - * ConfigurationManagement of capsulation of configuration properties with - * String keys, which are case insentive at lookup (at get, remove, put - * operations) but preserve the last case of keys. - * - * The implementaion of the Externalizable interface allows remote transfer of - * those properties. - * - * @author Pavlin Dobrev - * @version 1.0 - */ - -public class ExternalizableDictionary extends Dictionary implements Externalizable, Cloneable { - - private static Class[] CLASSES = new Class[] {ExternalizableDictionary.class}; - private HashtableEntry table[]; - private int count; - private int threshold; - private float loadFactor; - private static int MIN_CAPACITY = 5; - - ClassLoader loader; - - /** - * Constructs a new, empty dictionary with the specified initial capacity - * and the specified load factor. - * - * @param initialCapacity - * the initial capacity of the hashtable. when 0 is passed for - * capacity, minimum possible capacity is used; i.e. when the - * object is read as externalizable, then the table is created - * with the written size. - * @param loadFactor - * a number between 0.0 and 1.0. - * @exception IllegalArgumentException - * if the initial capacity is less than zero, or if the load - * factor is less than or equal to zero. - */ - public ExternalizableDictionary(int initialCapacity, float loadFactor) { - if ((initialCapacity < 0) || (loadFactor <= 0.0)) { - throw new IllegalArgumentException(); - } - this.loadFactor = loadFactor; - if (initialCapacity > 0) - initTable(initialCapacity); - } - - private void initTable(int initialCapacity) { - table = new HashtableEntry[initialCapacity]; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Constructs a new, empty dictionary with the wanted capacity and default - * load factor. - */ - public ExternalizableDictionary(int initialCapacity) { - this(initialCapacity, 0.75f); - } - - /** - * Constructs a new, empty dictionary with a default capacity and load - * factor. - */ - public ExternalizableDictionary() { - this(101, 0.75f); - } - - public ClassLoader setClassLaoder(ClassLoader loader) { - ClassLoader tmp = this.loader; - this.loader = loader; - return tmp; - } - - public ClassLoader setClassLoader(ClassLoader loader) { - ClassLoader tmp = this.loader; - this.loader = loader; - return tmp; - } - - public Class[] remoteInterfaces() { - return CLASSES; - } - - /** - * Gets the size of the elements in the dictionary. - * - * @return size of hashtable - */ - public int size() { - return count; - } - - /** - * Checks if there is any element in the dictionary. - * - * @return true if empty. - */ - public boolean isEmpty() { - return count == 0; - } - - /** - * Gets an enumeration with dictionary's keys. - * - * @return an enumeration with dictionary's keys. - */ - public synchronized Enumeration keys() { - return new HashtableEnumerator(table, true); - } - - /** - * Gets an enumeration with dictionary's values. - * - * @return an enumeration with dictionary's values. - */ - public synchronized Enumeration elements() { - return new HashtableEnumerator(table, false); - } - - private int hashCode(String key) { - return key.toLowerCase().hashCode(); - } - - /** - * Gets the value corresponding to this key or any of its case - * representations. - * - * @param key - * String key - * @return object value or null if none - */ - public synchronized Object get(Object key) { - if (table != null) { - HashtableEntry tab[] = table; - int hash = hashCode((String) key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - return e.value; - } - } - } - return null; - } - - protected void rehash() { - int oldCapacity = table.length; - HashtableEntry oldTable[] = table; - - int newCapacity = oldCapacity * 2 + 1; - HashtableEntry newTable[] = new HashtableEntry[newCapacity]; - - threshold = (int) (newCapacity * loadFactor); - table = newTable; - - for (int i = oldCapacity; i-- > 0;) { - for (HashtableEntry old = oldTable[i]; old != null;) { - HashtableEntry e = old; - old = old.next; - int index = (e.hash & 0x7FFFFFFF) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } - } - } - - /** - * Puts the key and the value in the table. If there already is a key equal - * ignore case to the one passed the new value exchhanes the old one. - * - * @param key - * String key - * @param value - * object to put - * @return old value if any, or null if none - * @exception IllegalArgumentException - * if key is not a string - */ - public synchronized Object put(Object key, Object value) throws IllegalArgumentException { - - if (value == null) { - throw new NullPointerException(); - } - if (table == null) - initTable(MIN_CAPACITY); - try { - // Makes sure the key is not already in the hashtable. - int hash = hashCode((String) key); - int index; - HashtableEntry[] tab = null; - do { - tab = table; - index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index]; e != null; e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - Object old = e.value; - e.value = value; - return old; - } - } - if (count >= threshold) { - // Rehash the table if the threshold is exceeded - rehash(); - continue; - } - break; - } while (true); - - // Creates the new entry. - HashtableEntry e = new HashtableEntry(); - e.hash = hash; - e.key = (String) key; - e.value = value; - e.next = tab[index]; - tab[index] = e; - count++; - return null; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("Non string keys are not accepted!"); - } - } - - /** - * Removes the key and its corresponding value. Key is searched case - * insensitively. - * - * @param key - * string key - * @return object removed or null if none - * @exception IllegalArgumentException - * if key is not s string - */ - public synchronized Object remove(Object key) throws IllegalArgumentException { - - if (table == null) - return null; - try { - HashtableEntry tab[] = table; - int hash = hashCode((String) key); - int index = (hash & 0x7FFFFFFF) % tab.length; - for (HashtableEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) { - if ((e.hash == hash) && e.key.equalsIgnoreCase((String) key)) { - if (prev != null) { - prev.next = e.next; - } else { - tab[index] = e.next; - } - count--; - return e.value; - } - } - return null; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("Non string keys are not accepted!"); - } - } - - /** - * Clears all elements from the distionary. - */ - public synchronized void clear() { - if (table == null) - return; - for (int index = table.length; --index >= 0;) { - table[index] = null; - } - count = 0; - } - - /** - * Creates a shallow copy of this hashtable. The keys and values themselves - * are not cloned. - * - * @return a new CMDictioanry with the same fields - */ - public synchronized Object clone() { - try { - ExternalizableDictionary cmDict = (ExternalizableDictionary) super.clone(); - if (table != null) { - cmDict.table = new HashtableEntry[table.length]; - for (int i = table.length; i-- > 0;) { - cmDict.table[i] = (table[i] != null) ? (HashtableEntry) table[i].clone() : null; - } - } - return cmDict; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Compares the specified Object with this Dictionary for equality, - * - * @return true if the specified Object is equal to this Dictionary. - */ - - public synchronized boolean equals(Object o) { - if (o == this) - return true; - if (!(o instanceof Dictionary)) - return false; - Dictionary dict = (Dictionary) o; - int max = size(); - if (dict.size() != max) - return false; - Enumeration k = keys(); - Enumeration e = elements(); - for (int i = 0; i < max; i++) { - Object key = k.nextElement(); - Object value = e.nextElement(); - if (!value.equals(dict.get(key))) { - return false; - } - } - return true; - } - - /** - * Makes a string represntation of this object. - * - * @return string represntation of this object - */ - public synchronized String toString() { - int max = size() - 1; - StringBuffer buf = new StringBuffer(); - Enumeration k = keys(); - Enumeration e = elements(); - buf.append('{'); - for (int i = 0; i <= max; i++) { - String s1 = (String) k.nextElement(); - String s2 = e.nextElement().toString(); - buf.append(s1); - buf.append('='); - buf.append(s2); - if (i < max) { - buf.append(','); - buf.append(' '); - } - } - buf.append('}'); - return buf.toString(); - } - - /** - * Writes this object to the stream passed. The object can be loaded again - * via its readObject method. - * - * @param os - * strream to write data to. - * @exception Exception - * if error of any kind occurs - */ - public synchronized void writeObject(OutputStream os) throws Exception { - Enumeration keys = keys(); - Enumeration values = elements(); - PDataStream.writeInt(size(), os); - // dictionary is never empty: - // it either has elements or is null - while (keys.hasMoreElements()) { - PDataStream.writeUTF((String) keys.nextElement(), os); - writeValue(values.nextElement(), os); - } - } - - private static void writeValue(Object value, OutputStream os) throws IOException { - - if (value == null) { - os.write(-1); - } else { - Class valueClass = value.getClass(); - // write 0 for a single value, 1 for array, and 2 for Vector - if (valueClass.isArray()) { - os.write(1); - int length = Array.getLength(value); - PDataStream.writeInt(length, os); - Class componentType = valueClass.getComponentType(); - if (componentType.isPrimitive()) { - // primitive - PDataStream.writeBoolean(true, os); - // 1: int;2: long; 3: byte; 4: boolean; 5: character; 6: - // short; 7: float; 8: double - writePrimitiveArray(componentType, value, length, os); - } else { - PDataStream.writeBoolean(false, os); - PDataStream.writeUTF(componentType.getName(), os); - Object[] oArr = (Object[]) value; - for (int i = 0; i < length; i++) { - writeValue(oArr[i], os); - } - } - } else if (valueClass.equals(Vector.class)) { - os.write(2); - int size = ((Vector) value).size(); - PDataStream.writeInt(size, os); - for (int i = 0; i < size; i++) { - writeValue(((Vector) value).elementAt(i), os); - } - } else { - os.write(0); - writeRealObject(value, valueClass, os); - } - } - } - - private static Object readValue(InputStream is, ClassLoader loader) throws Exception { - byte type = (byte) is.read(); - if (type == -1) { - return null; - } - Class vClass = null; - if (type == 2) { - int length = PDataStream.readInt(is); - Vector v = new Vector(length); - for (int i = 0; i < length; i++) { - v.insertElementAt(readValue(is, loader), i); - } - return v; - } else if (type == 0) { - return readRealObject((byte) is.read(), is, loader); - } else { - int length = PDataStream.readInt(is); - boolean primitive = PDataStream.readBoolean(is); - if (primitive) { - return readPrimitiveArray(length, is); - } - vClass = loader == null ? Class.forName(PDataStream.readUTF(is)) : loader.loadClass(PDataStream.readUTF(is)); - Object array = Array.newInstance(vClass, length); - for (int i = 0; i < length; i++) { - Array.set(array, i, readValue(is, loader)); - } - return array; - } - } - - /** - * Reads the data from the InputStream and loads the data in the table. - * - * @param is - * stream to read dictionary's data from - * @exception Exception - * if an error of any kind occurs while reading - */ - public synchronized void readObject(InputStream is) throws Exception { - try { - int size = PDataStream.readInt(is); - if (table == null) { - if (size > 0) { - initTable(size); - } else - initTable(MIN_CAPACITY); - } - for (int i = 0; i < size; i++) { - put(PDataStream.readUTF(is), readValue(is, loader)); - } - } catch (Exception e) { - throw e; - } - } - - // 1: int;2: long; 3: byte; 4: boolean; 5: character; - // 6: short; 7: float; 8: double - private static void writePrimitiveArray(Class componentType, Object array, int length, OutputStream os) throws IOException { - - if (componentType.equals(Integer.TYPE)) { - int[] ints = (int[]) array; - os.write(1); - for (int i = 0; i < length; i++) { - PDataStream.writeInt(ints[i], os); - } - } else if (componentType.equals(Long.TYPE)) { - os.write(2); - long[] longs = (long[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeLong(longs[i], os); - } - } else if (componentType.equals(Byte.TYPE)) { - os.write(3); - os.write((byte[]) array); - } else if (componentType.equals(Boolean.TYPE)) { - os.write(4); - boolean[] booleans = (boolean[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeBoolean(booleans[i], os); - } - } else if (componentType.equals(Character.TYPE)) { - os.write(5); - char[] chars = (char[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeChar(chars[i], os); - } - } else if (componentType.equals(Short.TYPE)) { - os.write(6); - short[] shorts = (short[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeShort(shorts[i], os); - } - } else if (componentType.equals(Float.TYPE)) { - os.write(7); - float[] floats = (float[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeFloat(floats[i], os); - } - } else if (componentType.equals(Double.TYPE)) { - os.write(8); - double[] doubles = (double[]) array; - for (int i = 0; i < length; i++) { - PDataStream.writeDouble(doubles[i], os); - } - } else { - throw new IllegalArgumentException("Unsupported Primitive Type: " + componentType); - } - } - - private static Object readPrimitiveArray(int length, InputStream is) throws IOException { - byte type = (byte) is.read(); - if (type == 1) { - int[] ints = new int[length]; - for (int i = 0; i < length; i++) { - ints[i] = PDataStream.readInt(is); - } - return ints; - } else if (type == 2) { - long[] longs = new long[length]; - for (int i = 0; i < length; i++) { - longs[i] = PDataStream.readLong(is); - } - return longs; - } else if (type == 3) { - byte[] bytes = new byte[length]; - is.read(bytes); - return bytes; - } else if (type == 4) { - boolean[] booleans = new boolean[length]; - for (int i = 0; i < length; i++) { - booleans[i] = PDataStream.readBoolean(is); - } - return booleans; - } else if (type == 5) { - char[] chars = new char[length]; - for (int i = 0; i < length; i++) { - chars[i] = PDataStream.readChar(is); - } - return chars; - } else if (type == 6) { - short[] shorts = new short[length]; - for (int i = 0; i < length; i++) { - shorts[i] = PDataStream.readShort(is); - } - return shorts; - } else if (type == 7) { - float[] floats = new float[length]; - for (int i = 0; i < length; i++) { - floats[i] = PDataStream.readFloat(is); - } - return floats; - } else if (type == 8) { - double[] doubles = new double[length]; - for (int i = 0; i < length; i++) { - doubles[i] = PDataStream.readDouble(is); - } - return doubles; - } else { - throw new IllegalArgumentException("Trying to read unsupported primitive type: " + type); - } - } - - // only if this is an object (not primitive) and non null! - private static void writeRealObject(Object value, Class vClass, OutputStream os) throws IOException { - try { - if (vClass.equals(String.class)) { - os.write(0); - PDataStream.writeUTF((String) value, os); - } else if (vClass.equals(Integer.class)) { - os.write(1); - PDataStream.writeInt(((Integer) value).intValue(), os); - } else if (vClass.equals(Long.class)) { - os.write(2); - PDataStream.writeLong(((Long) value).longValue(), os); - } else if (vClass.equals(Byte.class)) { - os.write(3); - os.write(((Byte) value).byteValue()); - } else if (vClass.equals(Boolean.class)) { - os.write(4); - PDataStream.writeBoolean(((Boolean) value).booleanValue(), os); - } else if (vClass.equals(Character.class)) { - os.write(5); - PDataStream.writeChar(((Character) value).charValue(), os); - } else if (vClass.equals(Short.class)) { - os.write(6); - PDataStream.writeShort(((Short) value).shortValue(), os); - } else if (vClass.equals(Float.class)) { - os.write(7); - PDataStream.writeFloat(((Float) value).floatValue(), os); - } else if (vClass.equals(Double.class)) { - os.write(8); - PDataStream.writeDouble(((Double) value).doubleValue(), os); - } else if (Externalizable.class.isAssignableFrom(vClass)) { - os.write(11); - String name = vClass.getName(); - PDataStream.writeUTF(name, os); - Externalizable tmp = (Externalizable) value; - tmp.writeObject(os); - } else { - os.write(12); - ObjectOutputStream out = new ObjectOutputStream(os); - out.writeObject(value); - } - } catch (Exception exc) { - throw new IOException(exc.toString()); - } - } - - private static Object readRealObject(byte type, InputStream is, ClassLoader loader) throws IOException { - try { - if (type == 0) { - return PDataStream.readUTF(is); - } else if (type == 1) { - return new Integer(PDataStream.readInt(is)); - } else if (type == 2) { - return new Long(PDataStream.readLong(is)); - } else if (type == 3) { - return new Byte((byte) is.read()); - } else if (type == 4) { - return PDataStream.readBoolean(is) ? Boolean.TRUE : Boolean.FALSE; - } else if (type == 5) { - return new Character(PDataStream.readChar(is)); - } else if (type == 6) { - return new Short(PDataStream.readShort(is)); - } else if (type == 7) { - return new Float(PDataStream.readFloat(is)); - } else if (type == 8) { - return new Double(PDataStream.readDouble(is)); - } else if (type == 11) { - String name = PDataStream.readUTF(is); - Class c = loader == null ? Class.forName(name) : loader.loadClass(name); - if (Externalizable.class.isAssignableFrom(c)) { - Externalizable obj = (Externalizable) c.newInstance(); - obj.readObject(is); - return obj; - } - throw new IOException("Could not read object " + name); - } else if (type == 12) { - ObjectInputStream in = loader == null ? new ObjectInputStream(is) : (ObjectInputStream) new XObjectInputStream(loader, is); - return in.readObject(); - } - } catch (ClassNotFoundException cnfe) { - throw new IOException("Could not find class " + cnfe.toString()); - } catch (Exception exc) { - throw exc instanceof IOException ? (IOException) exc : new IOException("Could not read object " + exc.toString()); - } - throw new IllegalArgumentException("Unsupported Typed Object: " + type); - } - - /** - * - * - * @param props - * @exception IllegalArgumentException - */ - public synchronized void copyFrom(Dictionary props) throws IllegalArgumentException { - Enumeration keys = props.keys(); - Enumeration values = props.elements(); - while (keys.hasMoreElements()) { - put(keys.nextElement(), values.nextElement()); - } - } - -} - -class HashtableEntry { - int hash; - String key; - Object value; - HashtableEntry next; - - protected Object clone() { - HashtableEntry entry = new HashtableEntry(); - entry.hash = hash; - entry.key = key; - entry.value = value; - entry.next = (next != null) ? (HashtableEntry) next.clone() : null; - return entry; - } -} - -class HashtableEnumerator implements Enumeration { - boolean keys; - int index; - HashtableEntry table[]; - HashtableEntry entry; - - HashtableEnumerator(HashtableEntry table[], boolean keys) { - this.table = table; - this.keys = keys; - this.index = table.length; - } - - public boolean hasMoreElements() { - if (table == null) - return false; - if (entry != null) { - return true; - } - while (index-- > 0) { - if ((entry = table[index]) != null) { - return true; - } - } - return false; - } - - public Object nextElement() { - if (table != null) { - if (entry == null) { - while ((index-- > 0) && ((entry = table[index]) == null)); - } - if (entry != null) { - HashtableEntry e = entry; - entry = e.next; - return keys ? e.key : e.value; - } - } - throw new NoSuchElementException("HashtableEnumerator"); - } -} - -class XObjectInputStream extends ObjectInputStream { - - ClassLoader loader; - - public XObjectInputStream(ClassLoader loader, InputStream is) throws IOException { - super(is); - this.loader = loader; - } - - protected Class resolveClass(ObjectStreamClass v) throws ClassNotFoundException { - return loader.loadClass(v.getName()); - } -} |