/******************************************************************************
* Copyright (c) 2006, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
* is available at http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* VMware Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.context.support;
import java.beans.PropertyEditor;
import java.io.IOException;
import java.io.InputStream;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.gemini.blueprint.context.BundleContextAware;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.ClassArrayEditor;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.CustomMapEditor;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.util.Assert;
/**
* Class that registers {@link PropertyEditor}s, useful inside an OSGi application context.
*
* As this class is used for bootstrapping and is likely to draw classes from various packages that already depend on
* {@link BundleContextAware}, the configuration has been externalized to avoid package cycles.
*
* @author Costin Leau
*/
class OsgiPropertyEditorRegistrar implements PropertyEditorRegistrar {
private static final Log log = LogFactory.getLog(OsgiPropertyEditorRegistrar.class);
private static final String PROPERTIES_FILE =
"/org/eclipse/gemini/blueprint/context/support/internal/default-property-editors.properties";
private final Map<Class<?>, Class<? extends PropertyEditor>> editors;
private final ClassLoader userClassLoader;
OsgiPropertyEditorRegistrar(ClassLoader userClassLoader) {
this.userClassLoader = userClassLoader;
// load properties
Properties editorsConfig = new Properties();
InputStream stream = null;
try {
stream = getClass().getResourceAsStream(PROPERTIES_FILE);
editorsConfig.load(stream);
} catch (IOException ex) {
throw (RuntimeException) new IllegalStateException(
"cannot load default propertiy editorsConfig configuration").initCause(ex);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ex) {
}
}
}
if (log.isTraceEnabled())
log.trace("Loaded property editors configuration " + editorsConfig);
editors = new LinkedHashMap<Class<?>, Class<? extends PropertyEditor>>(editorsConfig.size());
createEditors(editorsConfig);
}
@SuppressWarnings("unchecked")
private void createEditors(Properties configuration) {
boolean trace = log.isTraceEnabled();
// load properties using this class class loader
ClassLoader classLoader = getClass().getClassLoader();
for (Map.Entry<Object, Object> entry : configuration.entrySet()) {
// key represents type
Class<?> key;
// value represents property editor
Class<?> editorClass;
try {
key = classLoader.loadClass((String) entry.getKey());
editorClass = classLoader.loadClass((String) entry.getValue());
} catch (ClassNotFoundException ex) {
throw (RuntimeException) new IllegalArgumentException("Cannot load class").initCause(ex);
}
Assert.isAssignable(PropertyEditor.class, editorClass);
if (trace)
log.trace("Adding property editor[" + editorClass + "] for type[" + key + "]");
editors.put(key, (Class<? extends PropertyEditor>) editorClass);
}
}
public void registerCustomEditors(PropertyEditorRegistry registry) {
for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : editors.entrySet()) {
Class<?> type = entry.getKey();
PropertyEditor editorInstance;
editorInstance = BeanUtils.instantiate(entry.getValue());
registry.registerCustomEditor(type, editorInstance);
}
// register non-externalized types
registry.registerCustomEditor(Dictionary.class, new CustomMapEditor(Hashtable.class));
registry.registerCustomEditor(Properties.class, new PropertiesEditor());
registry.registerCustomEditor(Class.class, new ClassEditor(userClassLoader));
registry.registerCustomEditor(Class[].class, new ClassArrayEditor(userClassLoader));
}
}