Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java130
1 files changed, 57 insertions, 73 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
index bc80b1bfd..97d235090 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
@@ -13,102 +13,91 @@ package org.eclipse.osgi.internal.serviceregistry;
import java.lang.reflect.Array;
import java.util.*;
-import org.eclipse.osgi.framework.util.Headers;
+import org.eclipse.osgi.framework.util.CaseInsensitiveDictionaryMap;
+import org.eclipse.osgi.internal.messages.Msg;
+import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Constants;
/**
- * Hashtable for service properties.
+ * Service properties.
*
* Supports case-insensitive key lookup.
*/
-class ServiceProperties extends Headers<String, Object> {
+class ServiceProperties extends CaseInsensitiveDictionaryMap<String, Object> {
/**
- * Create a properties object for the service.
+ * Create a properties object from a Dictionary.
*
* @param props The properties for this service.
+ * @throws IllegalArgumentException If a case-variants of a key are
+ * in the props parameter.
*/
- private ServiceProperties(int size, Dictionary<String, ?> props) {
- super(size);
+ ServiceProperties(Dictionary<String, ?> props) {
+ this(props, 0);
+ }
+ /**
+ * Create a properties object from a Dictionary.
+ *
+ * @param props The properties for this service.
+ * @param extra Extra capacity in the map.
+ * @throws IllegalArgumentException If a case-variants of a key are
+ * in the props parameter.
+ */
+ ServiceProperties(Dictionary<String, ?> props, int extra) {
+ super(initialCapacity((props == null) ? extra : props.size() + extra));
if (props == null) {
return;
}
synchronized (props) {
Enumeration<?> keysEnum = props.keys();
-
while (keysEnum.hasMoreElements()) {
Object key = keysEnum.nextElement();
-
if (key instanceof String) {
String header = (String) key;
-
- setProperty(header, props.get(header));
+ if (putIfAbsent(header, cloneValue(props.get(header))) != null) {
+ throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
+ }
}
}
}
}
/**
- * Create a properties object for the service.
+ * Create a properties object from a Map.
*
* @param props The properties for this service.
+ * @throws IllegalArgumentException If a case-variants of a key are
+ * in the props parameter.
*/
- ServiceProperties(Dictionary<String, ?> props) {
- this((props == null) ? 2 : props.size() + 2, props);
- }
-
- /**
- * Get a clone of the value of a service's property.
- *
- * @param key header name.
- * @return Clone of the value of the property or <code>null</code> if there is
- * no property by that name.
- */
- Object getProperty(String key) {
- return cloneValue(get(key));
- }
-
- /**
- * Get the list of key names for the service's properties.
- *
- * @return The list of property key names.
- */
- synchronized String[] getPropertyKeys() {
- int size = size();
-
- String[] keynames = new String[size];
-
- Enumeration<String> keysEnum = keys();
-
- for (int i = 0; i < size; i++) {
- keynames[i] = keysEnum.nextElement();
+ ServiceProperties(Map<String, ?> props) {
+ super(initialCapacity((props == null) ? 0 : props.size()));
+ if (props == null) {
+ return;
+ }
+ synchronized (props) {
+ for (Entry<?, ?> e : props.entrySet()) {
+ Object key = e.getKey();
+ if (key instanceof String) {
+ String header = (String) key;
+ if (putIfAbsent(header, cloneValue(e.getValue())) != null) {
+ throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key));
+ }
+ }
+ }
}
-
- return keynames;
- }
-
- /**
- * Put a clone of the property value into this property object.
- *
- * @param key Name of property.
- * @param value Value of property.
- * @return previous property value.
- */
- synchronized Object setProperty(String key, Object value) {
- return set(key, cloneValue(value));
}
/**
* Attempt to clone the value if necessary and possible.
*
- * For some strange reason, you can test to see of an Object is
+ * For some strange reason, you can test to see if an Object is
* Cloneable but you can't call the clone method since it is
* protected on Object!
*
* @param value object to be cloned.
* @return cloned object or original object if we didn't clone it.
*/
- private static Object cloneValue(Object value) {
+ static Object cloneValue(Object value) {
if (value == null)
return null;
if (value instanceof String) /* shortcut String */
@@ -129,33 +118,28 @@ class ServiceProperties extends Headers<String, Object> {
System.arraycopy(value, 0, clonedArray, 0, len);
return clonedArray;
}
- // must use reflection because Object clone method is protected!!
- try {
- return clazz.getMethod("clone", (Class<?>[]) null).invoke(value, (Object[]) null); //$NON-NLS-1$
- } catch (Exception e) {
- /* clone is not a public method on value's class */
- } catch (Error e) {
- /* JCL does not support reflection; try some well known types */
- if (value instanceof Vector<?>)
- return ((Vector<?>) value).clone();
- if (value instanceof Hashtable<?, ?>)
- return ((Hashtable<?, ?>) value).clone();
+
+ if (value instanceof Cloneable) {
+ // must use reflection because Object clone method is protected!!
+ try {
+ return clazz.getMethod("clone", (Class<?>[]) null).invoke(value, (Object[]) null); //$NON-NLS-1$
+ } catch (Exception e) {
+ /* clone is not a public method on value's class */
+ }
}
return value;
}
- public synchronized String toString() {
- String keys[] = getPropertyKeys();
-
- int size = keys.length;
+ @Override
+ public String toString() {
+ Set<String> keys = keySet();
- StringBuilder sb = new StringBuilder(20 * size);
+ StringBuilder sb = new StringBuilder(20 * keys.size());
sb.append('{');
int n = 0;
- for (int i = 0; i < size; i++) {
- String key = keys[i];
+ for (String key : keys) {
if (!key.equals(Constants.OBJECTCLASS)) {
if (n > 0)
sb.append(", "); //$NON-NLS-1$

Back to the top