blob: d9dc6302ed7555096311ffbd17244a60a316e85c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2008 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 {
/**
* Create a properties object for the service.
*
* @param props The properties for this service.
*/
private ServiceProperties(int size, Dictionary 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 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 keysEnum = keys();
for (int i = 0; i < size; i++) {
keynames[i] = (String) 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", null).invoke(value, 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();
}
}