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.java186
1 files changed, 186 insertions, 0 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
new file mode 100644
index 000000000..a829d2697
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceProperties.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.serviceregistry;
+
+import java.lang.reflect.Array;
+import java.util.*;
+import org.eclipse.osgi.framework.util.Headers;
+import org.osgi.framework.Constants;
+
+/**
+ * Hashtable for service properties.
+ *
+ * Supports case-insensitive key lookup.
+ */
+class ServiceProperties extends Headers<String, Object> {
+ /**
+ * Create a properties object for the service.
+ *
+ * @param props The properties for this service.
+ */
+ private ServiceProperties(int size, Dictionary<String, ?> props) {
+ super(size);
+
+ 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));
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a properties object for the service.
+ *
+ * @param props The properties for this service.
+ */
+ 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();
+ }
+
+ 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
+ * 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) {
+ if (value == null)
+ return null;
+ if (value instanceof String) /* shortcut String */
+ return value;
+ if (value instanceof Number) /* shortcut Number */
+ return value;
+ if (value instanceof Character) /* shortcut Character */
+ return value;
+ if (value instanceof Boolean) /* shortcut Boolean */
+ return value;
+
+ Class<?> clazz = value.getClass();
+ if (clazz.isArray()) {
+ // Do an array copy
+ Class<?> type = clazz.getComponentType();
+ int len = Array.getLength(value);
+ Object clonedArray = Array.newInstance(type, len);
+ 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();
+ }
+ return value;
+ }
+
+ public synchronized String toString() {
+ String keys[] = getPropertyKeys();
+
+ int size = keys.length;
+
+ StringBuffer sb = new StringBuffer(20 * size);
+
+ sb.append('{');
+
+ int n = 0;
+ for (int i = 0; i < size; i++) {
+ String key = keys[i];
+ if (!key.equals(Constants.OBJECTCLASS)) {
+ if (n > 0)
+ sb.append(", "); //$NON-NLS-1$
+
+ sb.append(key);
+ sb.append('=');
+ Object value = get(key);
+ if (value.getClass().isArray()) {
+ sb.append('[');
+ int length = Array.getLength(value);
+ for (int j = 0; j < length; j++) {
+ if (j > 0)
+ sb.append(',');
+ sb.append(Array.get(value, j));
+ }
+ sb.append(']');
+ } else {
+ sb.append(value);
+ }
+ n++;
+ }
+ }
+
+ sb.append('}');
+
+ return sb.toString();
+ }
+} \ No newline at end of file

Back to the top