package org.nightlabs.jfire.trade.ui.articlecontainer.detail;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.nightlabs.eclipse.extension.AbstractEPProcessor;
import org.nightlabs.eclipse.extension.EPProcessorException;
import org.nightlabs.jfire.trade.ArticleContainer;
import org.nightlabs.jfire.trade.ui.TradePlugin;
import org.nightlabs.util.reflect.ReflectUtil;
/**
* This registry processes the extension-point <code>org.nightlabs.jfire.trade.ui.articleContainerEditFactory</code>
* and can provide an {@link ArticleContainerEditFactory} for a particular type (class)
* of {@link ArticleContainer}.
* <p>
* The registry applies inheritance resolving (including interfaces) while searching for a {@link ArticleContainerEditFactory}.
* This means registrations on sub-classes of an {@link ArticleContainer} implementation will overwrite those.
* </p>
*
* @author Alexander Bieber <!-- alex [AT] nightlabs [DOT] de -->
*/
public class ArticleContainerEditFactoryRegistry
extends AbstractEPProcessor
{
protected static final String FACTOY_ELEMENT_NAME = "articleContainerEditFactory"; //$NON-NLS-1$
protected static final String ARTICLE_CONTAINER_ATTRIBUTE_NAME = "articleContainerClass"; //$NON-NLS-1$
public static final String EXTENSION_POINT_ID = TradePlugin.getDefault().getBundle().getSymbolicName() + "." + FACTOY_ELEMENT_NAME; //$NON-NLS-1$
protected static ArticleContainerEditFactoryRegistry _sharedInstance = null;
private static boolean initializingSharedInstance = false;
public static synchronized ArticleContainerEditFactoryRegistry sharedInstance()
throws EPProcessorException
{
if (initializingSharedInstance)
throw new IllegalStateException("Circular call to the method sharedInstance() during initialization!"); //$NON-NLS-1$
if (_sharedInstance == null) {
initializingSharedInstance = true;
try {
_sharedInstance = new ArticleContainerEditFactoryRegistry();
_sharedInstance.process();
} finally {
initializingSharedInstance = false;
}
}
return _sharedInstance;
}
private Map<String, ArticleContainerEditFactory> articleContainerEditoFactories = new HashMap<String, ArticleContainerEditFactory>();
/**
* @see org.nightlabs.base.ui.extensionpoint.AbstractEPProcessor#getExtensionPointID()
*/
@Override
public String getExtensionPointID() {
return EXTENSION_POINT_ID;
}
@Override
public void processElement(IExtension extension, IConfigurationElement element) throws Exception {
if (element.getName().equals(FACTOY_ELEMENT_NAME)) {
String articleContainerClass = element.getAttribute(ARTICLE_CONTAINER_ATTRIBUTE_NAME);
ArticleContainerEditFactory factory = (ArticleContainerEditFactory) element.createExecutableExtension("class"); //$NON-NLS-1$
articleContainerEditoFactories.put(articleContainerClass, factory);
}
}
/**
* Searches the {@link ArticleContainerEditFactory} registered for the given articleContainerClass
* or one of its super-classes or super-interfaces.
*
* @param articleContainerClass The class-name of the {@link ArticleContainer} to search an edit for.
* @return Either an {@link ArticleContainerEditFactory} or <code>null</code> if none could be found.
*/
public ArticleContainerEditFactory getArticleContainerEditFactory(String articleContainerClass) {
Class<?> searchClass = null;
try {
searchClass = Class.forName(articleContainerClass);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not resolve ArticleContainer class: " + articleContainerClass, e); //$NON-NLS-1$
}
List<Class<?>> typeHierarchy = ReflectUtil.collectTypeHierarchy(searchClass);
for (Class<?> classInHierarchy : typeHierarchy) {
ArticleContainerEditFactory factory = articleContainerEditoFactories.get(classInHierarchy.getName());
if (factory != null)
return factory;
}
return null;
}
}