blob: f46e4a137906f52f6a59b6dd755c9f5b4ebce57a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 Cognos Incorporated, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.internal.cm;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;
import java.util.Map.Entry;
/**
* ConfigurationDictionary holds the actual configuration data and meets the various comparison
* requirements of the Configuration Admin Service specification.
*/
public class ConfigurationDictionary extends Dictionary<String, Object> implements Serializable {
private static final long serialVersionUID = -3583299578203095532L;
private static final Collection<Class<?>> simples = Arrays.asList(new Class<?>[] {String.class, Integer.class, Long.class, Float.class, Double.class, Byte.class, Short.class, Character.class, Boolean.class});
private static final Collection<Class<?>> simpleArrays = Arrays.asList(new Class<?>[] {String[].class, Integer[].class, Long[].class, Float[].class, Double[].class, Byte[].class, Short[].class, Character[].class, Boolean[].class});
private static final Collection<Class<?>> primitiveArrays = Arrays.asList(new Class<?>[] {long[].class, int[].class, short[].class, char[].class, byte[].class, double[].class, float[].class, boolean[].class});
static class CaseInsensitiveStringComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = 6501536810492374044L;
@Override
public int compare(String s1, String s2) {
return (s1).compareToIgnoreCase(s2);
}
}
protected final Map<String, Object> configurationProperties = Collections.synchronizedMap(new TreeMap<>(new CaseInsensitiveStringComparator()));
private static void validateValue(Object value) {
Class<?> clazz = value.getClass();
// Is it in the set of simple types
if (simples.contains(clazz))
return;
// Is it an array of primitives or simples
if (simpleArrays.contains(clazz) || primitiveArrays.contains(clazz))
return;
// Is it a Collection of simples
if (value instanceof Collection) {
for (Object simple : (Collection<?>) value) {
Class<?> containedClazz = simple.getClass();
if (!simples.contains(containedClazz)) {
throw new IllegalArgumentException(containedClazz.getName() + " in " + clazz.getName()); //$NON-NLS-1$
}
}
return;
}
throw new IllegalArgumentException(clazz.getName());
}
@Override
public Enumeration<Object> elements() {
return Collections.enumeration(configurationProperties.values());
}
@Override
public Object get(Object key) {
if (key == null)
throw new NullPointerException();
return configurationProperties.get(key);
}
@Override
public boolean isEmpty() {
return configurationProperties.isEmpty();
}
@Override
public Enumeration<String> keys() {
return Collections.enumeration(configurationProperties.keySet());
}
@Override
public Object put(String key, Object value) {
if (key == null || value == null)
throw new NullPointerException();
// Will throw an illegal argument exception if not a valid configuration property type
validateValue(value);
return configurationProperties.put(key, value);
}
@Override
public Object remove(Object key) {
if (key == null)
throw new NullPointerException();
return configurationProperties.remove(key);
}
@Override
public int size() {
return configurationProperties.size();
}
ConfigurationDictionary copy() {
ConfigurationDictionary result = new ConfigurationDictionary();
for (Entry<String, Object> entry : configurationProperties.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value.getClass().isArray()) {
int arrayLength = Array.getLength(value);
Object copyOfArray = Array.newInstance(value.getClass().getComponentType(), arrayLength);
System.arraycopy(value, 0, copyOfArray, 0, arrayLength);
result.configurationProperties.put(key, copyOfArray);
} else if (value instanceof Collection)
result.configurationProperties.put(key, new ArrayList<>((Collection<?>) value));
else
result.configurationProperties.put(key, value);
}
return result;
}
}