/*
* Copyright 2009-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jdal.ui.bind;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.ClassUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdal.logic.CollectionPersistenceService;
import org.jdal.ui.View;
/**
* Configurable Binder Factory that use a Map ComponentClass -> BinderClass
* to create Binders for Swing components.
*
* Registered binders has preference over control accessor binder created from
* {@link ControlAccessorFactory}
*
* @author Jose Luis Martin.
* @since 1.1
*/
public class ConfigurableBinderFactory implements BinderFactory {
private final static Log log = LogFactory.getLog(BinderFactory.class);
private static BinderFactory defaultFactory;
private ControlAccessorFactory controlAccessorFactory;
private Map<Class<?>, Class<?extends PropertyBinder>> binders =
new Hashtable<Class<?>, Class<? extends PropertyBinder>>();
private boolean mergeBinders = true;
public ConfigurableBinderFactory() {
this(ConfigurableControlAccessorFactory.getDefaultFactory());
}
public ConfigurableBinderFactory(ControlAccessorFactory controlAccessorFactory) {
this.controlAccessorFactory = controlAccessorFactory;
initDefaultBinders();
}
/**
* Try to find a binder for a Class, use super Class if none is configured.
*
* @param clazz Class to looking for
* @return a Binder for that class or null if none
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public PropertyBinder getBinder(Class<?> clazz) {
Class<?extends PropertyBinder> binderClass = null;
PropertyBinder binder = null;
binderClass = binders.get(clazz);
if (binderClass == null) { // try with superclasses
List superclasses = ClassUtils.getAllSuperclasses(clazz);
superclasses.addAll(ClassUtils.getAllInterfaces(clazz));
Iterator iter = superclasses.iterator();
while (iter.hasNext() && binderClass == null) {
binderClass = binders.get(iter.next());
}
}
if (binderClass != null) {
try {
binder = binderClass.newInstance();
} catch (InstantiationException e) {
log.error(e);
} catch (IllegalAccessException e) {
log.error(e);
}
}
else {
binder = new ControlBinder(controlAccessorFactory);
}
return binder;
}
private void initDefaultBinders() {
binders.put(View.class, ViewBinder.class);
binders.put(CollectionPersistenceService.class, CollectionPersistentServiceBinder.class);
}
// Getters and Setters
public static synchronized BinderFactory getDefaultFactory() {
if (defaultFactory == null)
defaultFactory = new ConfigurableBinderFactory();
return defaultFactory;
}
public Map<Class<?>, Class<?extends PropertyBinder>> getBinders() {
return binders;
}
public void setBinders(Map<Class<?>, Class<?extends PropertyBinder>> binders) {
if (!mergeBinders)
this.binders.clear();
this.binders.putAll(binders);
}
/**
* @return the controlAccessorFactory
*/
public ControlAccessorFactory getControlAccessorFactory() {
return controlAccessorFactory;
}
/**
* @param controlAccessorFactory the controlAccessorFactory to set
*/
public void setControlAccessorFactory(ControlAccessorFactory controlAccessorFactory) {
this.controlAccessorFactory = controlAccessorFactory;
}
/**
* @return the mergeBinders
*/
public boolean isMergeBinders() {
return mergeBinders;
}
/**
* @param mergeBinders the mergeBinders to set
*/
public void setMergeBinders(boolean mergeBinders) {
this.mergeBinders = mergeBinders;
}
}