/**
*
*/
package org.nightlabs.jfire.issuetracking.ui.issuelink;
import java.util.ArrayList;
import java.util.Collections;
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.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.nightlabs.eclipse.extension.AbstractEPProcessor;
import org.nightlabs.eclipse.extension.EPProcessorException;
/**
* @author Chairat Kongarayawetchakun - chairat at nightlabs dot de
*
*/
public class IssueLinkHandlerFactoryRegistry
extends AbstractEPProcessor
{
protected static IssueLinkHandlerFactoryRegistry _sharedInstance = null;
public static final String EXTENSION_POINT_ID = "org.nightlabs.jfire.issuetracking.ui.issueLinkHandlerFactory"; //$NON-NLS-1$
public static final String ELEMENT_CATEGORY = "issueLinkHandlerCategory"; //$NON-NLS-1$
public static final String ELEMENT_FACTORY = "issueLinkHandlerFactory"; //$NON-NLS-1$
public static final String ATTRIBUTE_CATEGORY_ID = "categoryId"; //$NON-NLS-1$
public static final String ATTRIBUTE_PARENT_CATEGORY_ID = "parentCategoryId"; //$NON-NLS-1$
public static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
public static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
public static final String ATTRIBUTE_ID = "id"; //$NON-NLS-1$
public static final String ATTRIBUTE_ICON = "icon"; //$NON-NLS-1$
public static synchronized IssueLinkHandlerFactoryRegistry sharedInstance()
throws EPProcessorException
{
if (_sharedInstance == null) {
_sharedInstance = new IssueLinkHandlerFactoryRegistry();
_sharedInstance.process();
}
return _sharedInstance;
}
private Map<Class<? extends Object>, IssueLinkHandlerFactory> factories = new HashMap<Class<? extends Object>, IssueLinkHandlerFactory>();
private Map<String, List<IssueLinkHandlerCategory>> parentCategoryId2Categories = new HashMap<String, List<IssueLinkHandlerCategory>>();
private Map<String, List<IssueLinkHandlerFactory>> parentCategoryId2Factories = new HashMap<String, List<IssueLinkHandlerFactory>>();
protected IssueLinkHandlerFactory getFactory(Class<? extends Object> linkedObjectClass,
boolean throwExceptionIfNotFound)
{
IssueLinkHandlerFactory factory = factories.get(linkedObjectClass);
if (throwExceptionIfNotFound && factory == null)
throw new IllegalStateException("No IssueLinkHandlerFactory registered for linkedObjectClass=\""+ linkedObjectClass +"\""); //$NON-NLS-1$ //$NON-NLS-2$
return factory;
}
public List<IssueLinkHandlerCategory> getTopLevelCategories() {
List<IssueLinkHandlerCategory> cats = parentCategoryId2Categories.get(null);
if (cats == null)
return Collections.emptyList();
return Collections.unmodifiableList(cats);
}
public IssueLinkHandlerFactory getIssueLinkHandlerFactory(Class<?> linkedObjectClass) {
// Check for direct class
IssueLinkHandlerFactory factory = factories.get(linkedObjectClass);
if (factory == null) {
// check hierarchy here
Class<?> sClass = linkedObjectClass.getSuperclass();
while (!sClass.equals(Object.class)) {
factory = factories.get(linkedObjectClass);
if (factory != null)
break;
}
}
if (factory == null) {
return new DefaultIssueLinkHandlerFactory();
}
return factory;
}
protected void addFactory(IssueLinkHandlerFactory factory)
{
factories.put(factory.getLinkedObjectClass(), factory);
List<IssueLinkHandlerFactory> cats = parentCategoryId2Factories.get(factory.getCategoryId());
if (cats == null) {
cats = new ArrayList<IssueLinkHandlerFactory>();
parentCategoryId2Factories.put(factory.getCategoryId(), cats);
}
cats.add(factory);
}
@Override
public String getExtensionPointID()
{
return "org.nightlabs.jfire.issuetracking.ui.issueLinkHandlerFactory"; //$NON-NLS-1$
}
@Override
public void processElement(IExtension extension, IConfigurationElement element)
throws Exception
{
if (element.getName().equals(ELEMENT_FACTORY)) { //$NON-NLS-1$
processIssueLinkHandlerFactory(extension, element);
} else if (element.getName().equals(ELEMENT_CATEGORY)) { //$NON-NLS-1$
processIssueLinkHandlerCategory(extension, element);
}
}
private void processIssueLinkHandlerFactory(IExtension extension, IConfigurationElement element) throws Exception {
try {
IssueLinkHandlerFactory factory = (IssueLinkHandlerFactory) element.createExecutableExtension(ATTRIBUTE_CLASS); //$NON-NLS-1$
String name = element.getAttribute(ATTRIBUTE_NAME); //$NON-NLS-1$
String iconString = element.getAttribute(ATTRIBUTE_ICON);
factory.setName(name);
if (checkString(iconString)) {
ImageDescriptor imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(
extension.getNamespaceIdentifier(), iconString);
if (imageDescriptor != null)
factory.setImage(imageDescriptor.createImage());
}
addFactory(factory);
} catch (Throwable t) {
throw new EPProcessorException("Extension to "+getExtensionPointID()+" with class "+element.getAttribute("class")+" has errors!", t); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
}
private void processIssueLinkHandlerCategory(IExtension extension, IConfigurationElement element) throws Exception {
String categoryId = element.getAttribute(ATTRIBUTE_ID); //$NON-NLS-1$
String name = element.getAttribute(ATTRIBUTE_NAME); //$NON-NLS-1$
String parentCategoryId = element.getAttribute(ATTRIBUTE_PARENT_CATEGORY_ID); //$NON-NLS-1$
String iconString = element.getAttribute(ATTRIBUTE_ICON);
IssueLinkHandlerCategory category = new IssueLinkHandlerCategory();
category.setCategoryId(categoryId);
category.setName(name);
if ("".equals(parentCategoryId)) { //$NON-NLS-1$
parentCategoryId = null;
}
category.setParentCategoryId(parentCategoryId);
if (checkString(iconString)) {
ImageDescriptor imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(
extension.getNamespaceIdentifier(), iconString);
if (imageDescriptor != null)
category.setImage(imageDescriptor.createImage());
}
List<IssueLinkHandlerCategory> cats = parentCategoryId2Categories.get(parentCategoryId);
if (cats == null) {
cats = new ArrayList<IssueLinkHandlerCategory>();
parentCategoryId2Categories.put(parentCategoryId, cats);
}
cats.add(category);
}
@Override
public synchronized void process() {
super.process();
List<IssueLinkHandlerCategory> tops = getTopLevelCategories();
for (IssueLinkHandlerCategory topCat : tops) {
validateCategory(topCat);
}
}
private void validateCategory(IssueLinkHandlerCategory category) {
List<IssueLinkHandlerFactory> factories = parentCategoryId2Factories.get(category.getCategoryId());
if (factories != null) {
for (IssueLinkHandlerFactory childFactory : factories) {
category.addChildFactory(childFactory);
}
}
List<IssueLinkHandlerCategory> children = parentCategoryId2Categories.get(category.getCategoryId());
if (children != null) {
for (IssueLinkHandlerCategory child : children) {
category.addChildCategory(child);
child.setParent(category);
validateCategory(child);
}
}
}
}