Release OSGi API generified.
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/CopyOnWriteIdentityMap.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/CopyOnWriteIdentityMap.java
index 6345a3f..89bccb1 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/CopyOnWriteIdentityMap.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/CopyOnWriteIdentityMap.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 2010 IBM Corporation and others.
* 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
@@ -23,24 +23,25 @@
*
* @since 3.5
*/
-public class CopyOnWriteIdentityMap implements Map {
+public class CopyOnWriteIdentityMap<K, V> implements Map<K, V> {
/**
* The empty array singleton instance.
*/
+ @SuppressWarnings("unchecked")
private static final Entry[] emptyArray = new Entry[0];
/**
* The array of entries. This field is volatile so it can be
* accessed from unsynchronized reader methods.
*/
- private volatile Entry[] entries;
+ private volatile Entry<K, V>[] entries;
/**
* Creates an empty map.
*
*/
public CopyOnWriteIdentityMap() {
- entries = emptyArray;
+ entries = empty();
}
/**
@@ -48,8 +49,10 @@
*
* @param source The CopyOnWriteMap to copy.
*/
- public CopyOnWriteIdentityMap(CopyOnWriteIdentityMap source) {
- this.entries = source.entries();
+ public CopyOnWriteIdentityMap(CopyOnWriteIdentityMap<? extends K, ? extends V> source) {
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] toCopy = (Entry<K, V>[]) source.entries();
+ this.entries = toCopy;
}
/* These methods modify the map and are synchronized. */
@@ -66,7 +69,7 @@
* Otherwise the previous value of the key.
* @throws IllegalArgumentException If key is null.
*/
- public synchronized Object put(Object key, Object value) {
+ public synchronized V put(K key, V value) {
if (key == null) {
throw new IllegalArgumentException();
}
@@ -74,23 +77,25 @@
int size = entries.length;
for (int i = 0; i < size; i++) {
if (entries[i].key == key) {
- Object v = entries[i].value;
+ V v = entries[i].value;
if (v == value) {
return v;
}
- Entry[] newEntries = new Entry[size];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] newEntries = new Entry[size];
System.arraycopy(entries, 0, newEntries, 0, size);
- newEntries[i] = new Entry(key, value);
+ newEntries[i] = new Entry<K, V>(key, value);
entries = newEntries;
return v;
}
}
- Entry[] newEntries = new Entry[size + 1];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] newEntries = new Entry[size + 1];
if (size > 0) {
System.arraycopy(entries, 0, newEntries, 0, size);
}
- newEntries[size] = new Entry(key, value);
+ newEntries[size] = new Entry<K, V>(key, value);
entries = newEntries;
return null;
}
@@ -100,21 +105,22 @@
*
* @param source The map whose entries are to be added to this map.
*/
- public void putAll(Map source) {
+ public void putAll(Map<? extends K, ? extends V> source) {
int sourceSize = source.size();
if (sourceSize == 0) {
return;
}
- if (source instanceof CopyOnWriteIdentityMap) {
- putAll(((CopyOnWriteIdentityMap) source).entries());
+ if (source instanceof CopyOnWriteIdentityMap<?, ?>) {
+ putAll(((CopyOnWriteIdentityMap<? extends K, ? extends V>) source).entries());
return;
}
- Entry[] toCopy = new Entry[sourceSize];
- Iterator iter = source.entrySet().iterator();
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] toCopy = new Entry[sourceSize];
+ Iterator<? extends Map.Entry<? extends K, ? extends V>> iter = source.entrySet().iterator();
for (int i = 0; i < sourceSize; i++) {
- Map.Entry mapEntry = (Map.Entry) iter.next();
- toCopy[i] = new Entry(mapEntry.getKey(), mapEntry.getValue());
+ Map.Entry<? extends K, ? extends V> mapEntry = iter.next();
+ toCopy[i] = new Entry<K, V>(mapEntry.getKey(), mapEntry.getValue());
}
putAll(toCopy);
}
@@ -125,14 +131,15 @@
*
* @param keys The array of keys to be added to this map.
*/
- public void putAll(Object[] keys) {
+ public <L extends K> void putAll(L[] keys) {
int sourceSize = keys.length;
if (sourceSize == 0) {
return;
}
- Entry[] toCopy = new Entry[sourceSize];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] toCopy = new Entry[sourceSize];
for (int i = 0; i < sourceSize; i++) {
- toCopy[i] = new Entry(keys[i], null);
+ toCopy[i] = new Entry<K, V>(keys[i], null);
}
putAll(toCopy);
}
@@ -142,13 +149,15 @@
*
* @param toCopy Array of entries to add to this map.
*/
- private synchronized void putAll(Entry[] toCopy) {
+ private synchronized void putAll(Entry<? extends K, ? extends V>[] toCopy) {
int sourceSize = toCopy.length;
int size = entries.length;
- Entry[] newEntries = new Entry[size + sourceSize];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] newEntries = new Entry[size + sourceSize];
System.arraycopy(entries, 0, newEntries, 0, size);
copy: for (int n = 0; n < sourceSize; n++) {
- Entry copy = toCopy[n];
+ @SuppressWarnings("unchecked")
+ Entry<K, V> copy = (Entry<K, V>) toCopy[n];
for (int i = 0; i < size; i++) {
if (newEntries[i].key == copy.key) {
newEntries[i] = copy;
@@ -162,7 +171,8 @@
entries = newEntries;
return;
}
- Entry[] e = new Entry[size];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] e = new Entry[size];
System.arraycopy(newEntries, 0, e, 0, size);
entries = e;
}
@@ -176,7 +186,7 @@
* Otherwise, the value associated with the key.
* @throws IllegalArgumentException If key is null.
*/
- public synchronized Object remove(Object key) {
+ public synchronized V remove(Object key) {
if (key == null) {
throw new IllegalArgumentException();
}
@@ -184,12 +194,13 @@
int size = entries.length;
for (int i = 0; i < size; i++) {
if (entries[i].key == key) {
- Object v = entries[i].value;
+ V v = entries[i].value;
if (size == 1) {
- entries = emptyArray;
+ entries = empty();
return v;
}
- Entry[] newEntries = new Entry[size - 1];
+ @SuppressWarnings("unchecked")
+ Entry<K, V>[] newEntries = new Entry[size - 1];
if (i > 0) {
System.arraycopy(entries, 0, newEntries, 0, i);
}
@@ -209,7 +220,7 @@
*
*/
public synchronized void clear() {
- entries = emptyArray;
+ entries = empty();
}
/* These methods only read the map and are not synchronized. */
@@ -219,11 +230,20 @@
* @return The array of entries. Callers to this method MUST NOT
* modify the returned array.
*/
- private Entry[] entries() {
+ private Entry<K, V>[] entries() {
return entries;
}
/**
+ * Return the static empty array generically type safe.
+ * @return The empty array of entries.
+ */
+ @SuppressWarnings("unchecked")
+ private static <K, V> Entry<K, V>[] empty() {
+ return emptyArray;
+ }
+
+ /**
* Is the map empty?
*
* @return <code>true</code> if the list is empty.
@@ -249,12 +269,12 @@
* @return The value object for the specified key.
* @throws IllegalArgumentException If key is null.
*/
- public Object get(Object key) {
+ public V get(Object key) {
if (key == null) {
throw new IllegalArgumentException();
}
- Entry[] e = entries();
+ Entry<K, V>[] e = entries();
for (int i = 0; i < e.length; i++) {
if (e[i].key == key) {
return e[i].value;
@@ -276,7 +296,7 @@
throw new IllegalArgumentException();
}
- Entry[] e = entries();
+ Entry<K, V>[] e = entries();
for (int i = 0; i < e.length; i++) {
if (e[i].key == key) {
return true;
@@ -293,7 +313,7 @@
* @return <code>true</code> if the specified value is in the map.
*/
public boolean containsValue(Object value) {
- Entry[] e = entries();
+ Entry<K, V>[] e = entries();
for (int i = 0; i < e.length; i++) {
if (e[i].value == value) {
return true;
@@ -309,8 +329,8 @@
* @return A Set of Map.Entry for each entry in this map.
* The set and the entries returned by the set cannot be modified.
*/
- public Set entrySet() {
- return new EntrySet(entries(), EntrySet.ENTRY);
+ public Set<Map.Entry<K, V>> entrySet() {
+ return new EntrySet<Map.Entry<K, V>>(entries(), EntrySet.ENTRY);
}
/**
@@ -320,8 +340,8 @@
* @return A Set of the key objects in this map
* The set cannot be modified.
*/
- public Set keySet() {
- return new EntrySet(entries(), EntrySet.KEY);
+ public Set<K> keySet() {
+ return new EntrySet<K>(entries(), EntrySet.KEY);
}
/**
@@ -331,44 +351,44 @@
* @return A Collection of the value objects in this map.
* The collection cannot be modified.
*/
- public Collection values() {
- return new EntrySet(entries(), EntrySet.VALUE);
+ public Collection<V> values() {
+ return new EntrySet<V>(entries(), EntrySet.VALUE);
}
/**
* This class represents the entry in this Map.
* Entry is immutable.
*/
- private static class Entry implements Map.Entry {
+ private static class Entry<K, V> implements Map.Entry<K, V> {
/**
* Key object.
*/
- final Object key;
+ final K key;
/**
* Value object.
*/
- final Object value;
+ final V value;
/**
* Constructor for map entry.
* @param key Key object in entry. Used for uniqueness.
* @param value Value object stored with key object.
*/
- Entry(final Object key, final Object value) {
+ Entry(final K key, final V value) {
this.key = key;
this.value = value;
}
- public Object getKey() {
+ public K getKey() {
return key;
}
- public Object getValue() {
+ public V getValue() {
return value;
}
- public Object setValue(Object value) {
+ public V setValue(V value) {
throw new UnsupportedOperationException(); // entries cannot be modified.
}
}
@@ -378,20 +398,20 @@
*
* This class is immutable.
*/
- private static class EntrySet extends AbstractSet {
- private final Entry[] entries;
+ private static class EntrySet<E> extends AbstractSet<E> {
+ private final Entry<?, ?>[] entries;
private final int returnType;
final static int ENTRY = 1;
final static int KEY = 2;
final static int VALUE = 3;
- EntrySet(Entry[] entries, int returnType) {
+ EntrySet(Entry<?, ?>[] entries, int returnType) {
this.entries = entries;
this.returnType = returnType;
}
- public Iterator iterator() {
- return new EntryIterator(entries, returnType);
+ public Iterator<E> iterator() {
+ return new EntryIterator<E>(entries, returnType);
}
public int size() {
@@ -403,12 +423,12 @@
* Iterator class used for entry and key sets and values collections.
*
*/
- private static class EntryIterator implements Iterator {
- private final Entry[] entries;
+ private static class EntryIterator<E> implements Iterator<E> {
+ private final Entry<?, ?>[] entries;
private final int returnType;
private int cursor = 0;
- EntryIterator(Entry[] entries, int returnType) {
+ EntryIterator(Entry<?, ?>[] entries, int returnType) {
this.entries = entries;
this.returnType = returnType;
}
@@ -417,17 +437,23 @@
return cursor < entries.length;
}
- public Object next() {
+ public E next() {
if (cursor == entries.length) {
throw new NoSuchElementException();
}
switch (returnType) {
case EntrySet.ENTRY :
- return entries[cursor++];
+ @SuppressWarnings("unchecked")
+ E entry = (E) entries[cursor++];
+ return entry;
case EntrySet.KEY :
- return entries[cursor++].key;
+ @SuppressWarnings("unchecked")
+ E key = (E) entries[cursor++].key;
+ return key;
case EntrySet.VALUE :
- return entries[cursor++].value;
+ @SuppressWarnings("unchecked")
+ E value = (E) entries[cursor++].value;
+ return value;
}
throw new InternalError();
}