/*******************************************************************************
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* All rights reserved. This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package gov.redhawk.ide.codegen.ui.internal;
import gov.redhawk.ide.codegen.RedhawkCodegenActivator;
import gov.redhawk.ide.codegen.ui.DefaultGeneratorDisplayFactory;
import gov.redhawk.ide.codegen.ui.ICodeGeneratorPageRegistry2;
import gov.redhawk.ide.codegen.ui.ICodegenComposite;
import gov.redhawk.ide.codegen.ui.ICodegenDisplayFactory;
import gov.redhawk.ide.codegen.ui.ICodegenDisplayFactory2;
import gov.redhawk.ide.codegen.ui.ICodegenWizardPage;
import gov.redhawk.ide.codegen.ui.RedhawkCodegenUiActivator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IFilter;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.widgets.FormToolkit;
public class CodeGeneratorPageRegistry implements ICodeGeneratorPageRegistry2, IExtensionChangeHandler {
public static final String EP_ID = "codegenPages";
/**
* The Constant ATTR_CODEGEN
*/
private static final String ELM_CODEGEN = "codegenPage";
/**
* The Constant ATTR_CODEGEN
*/
private static final String ELM_CODEGEN_ID = "codegenId";
/**
* The Constant ATTR_CODEGEN
*/
private static final String ATTR_TARGET_CODEGEN_ID = "targetCodegenId";
private static final String ATTR_WIZARD_CLASS = "wizardClass";
private static final String ATTR_COMP_CLASS = "compositeClass";
/**
* Create a tracker.
*/
private final ExtensionTracker tracker;
/**
* The map of codegen id's to Codegen Wizard page objects.
*/
private final Map<String, List<ICodegenDisplayFactory>> codegenToWizardMap = new HashMap<String, List<ICodegenDisplayFactory>>();
/**
* The map of codegen id's to Codegen Composite page objects.
*/
private final Map<String, List<ICodegenDisplayFactory>> codegenToCompositeMap = new HashMap<String, List<ICodegenDisplayFactory>>();
private final DefaultGeneratorDisplayFactory defaultFactory = new DefaultGeneratorDisplayFactory();
public CodeGeneratorPageRegistry() {
final IExtensionRegistry reg = Platform.getExtensionRegistry();
final IExtensionPoint ep = reg.getExtensionPoint(RedhawkCodegenUiActivator.PLUGIN_ID, CodeGeneratorPageRegistry.EP_ID);
this.tracker = new ExtensionTracker(reg);
if (ep != null) {
final IFilter filter = ExtensionTracker.createExtensionPointFilter(ep);
this.tracker.registerHandler(this, filter);
final IExtension[] extensions = ep.getExtensions();
for (final IExtension extension : extensions) {
addExtension(this.tracker, extension);
}
}
}
@Override
public void addExtension(final IExtensionTracker tracker, final IExtension extension) {
final IConfigurationElement[] configs = extension.getConfigurationElements();
for (final IConfigurationElement element : configs) {
final ICodegenDisplayFactory factory = addConfig(element);
if (factory != null) {
tracker.registerObject(extension, factory, IExtensionTracker.REF_SOFT);
}
}
}
private ICodegenDisplayFactory addConfig(final IConfigurationElement element) {
ICodegenDisplayFactory factory = null;
if (element.getName().equals(CodeGeneratorPageRegistry.ELM_CODEGEN)) {
// Check if there's a wizard pages defined, if so, add it to the
// list of available wizard pages
final String wizardClassId = element.getAttribute(CodeGeneratorPageRegistry.ATTR_WIZARD_CLASS);
if (wizardClassId != null) {
try {
// Use the element to instantiate the specified class
factory = (ICodegenDisplayFactory) element.createExecutableExtension(CodeGeneratorPageRegistry.ATTR_WIZARD_CLASS);
// Loop through all of the codegenId elements and add this factory to the codegen listed
for (final IConfigurationElement elem : element.getChildren(CodeGeneratorPageRegistry.ELM_CODEGEN_ID)) {
final String codegenId = elem.getAttribute(CodeGeneratorPageRegistry.ATTR_TARGET_CODEGEN_ID);
// Get the list of factories for the specified code generator, create a new list if needed
List<ICodegenDisplayFactory> ids = this.codegenToWizardMap.get(codegenId);
if (ids == null) {
ids = new ArrayList<ICodegenDisplayFactory>();
this.codegenToWizardMap.put(codegenId, ids);
}
// Only add the factory if it's not already in the list
if (!ids.contains(factory)) {
ids.add(factory);
}
}
} catch (final CoreException e) {
RedhawkCodegenActivator.logError("Could not instantiate Code Generator Display Factory with an ID of: " + wizardClassId, null);
}
} else {
RedhawkCodegenActivator.logError("Unable to find wizard class ID for element: " + element.getName() + " (value: " + element.getValue() + ")", null);
}
// Check if there's a composite defined, if so, add it to the
// list of available composites
final String compositeClassId = element.getAttribute(CodeGeneratorPageRegistry.ATTR_COMP_CLASS);
if (compositeClassId != null) {
try {
// Use the element to instantiate the specified class
factory = (ICodegenDisplayFactory) element.createExecutableExtension(CodeGeneratorPageRegistry.ATTR_COMP_CLASS);
// Loop through all of the codegenId elements and add this factory to the codegen listed
for (final IConfigurationElement elem : element.getChildren(CodeGeneratorPageRegistry.ELM_CODEGEN_ID)) {
final String codegenId = elem.getAttribute(CodeGeneratorPageRegistry.ATTR_TARGET_CODEGEN_ID);
// Get the list of factories for the specified code generator, create a new list if needed
List<ICodegenDisplayFactory> ids = this.codegenToCompositeMap.get(codegenId);
if (ids == null) {
ids = new ArrayList<ICodegenDisplayFactory>();
this.codegenToCompositeMap.put(codegenId, ids);
}
// Only add the factory if it's not already in the list
if (!ids.contains(factory)) {
ids.add(factory);
}
}
} catch (final CoreException e) {
RedhawkCodegenActivator.logError("Could not instantiate Code Generator Display Factory with an ID of: " + compositeClassId, null);
}
} else {
RedhawkCodegenActivator.logError("Unable to find composite class ID for element: " + element.getName() + " (value: " + element.getValue() + ")", null);
}
}
return factory;
}
@Override
public void removeExtension(final IExtension extension, final Object[] objects) {
for (final Object obj : objects) {
if (obj instanceof ICodegenDisplayFactory) {
// TODO make this work
// NOTE! THIS DOES NOT WORK!
final ICodegenDisplayFactory guiId = (ICodegenDisplayFactory) obj;
List<ICodegenDisplayFactory> ids = this.codegenToWizardMap.get(guiId);
ids.remove(guiId);
if (ids.size() == 0) {
this.codegenToWizardMap.remove(guiId);
}
ids = this.codegenToCompositeMap.get(guiId);
ids.remove(guiId);
if (ids.size() == 0) {
this.codegenToCompositeMap.remove(guiId);
}
}
}
}
@Override
public ICodegenWizardPage[] getDefaultPages() {
List<ICodegenWizardPage> pages = new ArrayList<ICodegenWizardPage>();
pages.add(this.defaultFactory.createPage());
return pages.toArray(new ICodegenWizardPage[1]);
}
@Override
public ICodegenWizardPage[] findPageByGeneratorId(final String codegen) {
final ArrayList<ICodegenWizardPage> codegens = new ArrayList<ICodegenWizardPage>();
final List<ICodegenDisplayFactory> factories = this.codegenToWizardMap.get(codegen);
if (factories != null) {
for (final ICodegenDisplayFactory factory : factories) {
if (factory instanceof ICodegenDisplayFactory2) {
final ICodegenWizardPage[] wizPages = ((ICodegenDisplayFactory2) factory).createPages();
codegens.addAll(Arrays.asList(wizPages));
} else {
codegens.add(factory.createPage());
}
}
}
if (codegens.size() == 0) {
codegens.addAll(Arrays.asList(this.defaultFactory.createPage()));
}
return codegens.toArray(new ICodegenWizardPage[codegens.size()]);
}
@Override
public ICodegenComposite getDefaultComposite(final Composite parent, final int style, final FormToolkit toolkit) {
return this.defaultFactory.createComposite(parent, style, toolkit);
}
@Override
public ICodegenComposite[] findCompositeByGeneratorId(final String codegen, final Composite parent, final int style, final FormToolkit toolkit) {
final ArrayList<ICodegenComposite> codegens = new ArrayList<ICodegenComposite>();
final List<ICodegenDisplayFactory> factories = this.codegenToCompositeMap.get(codegen);
if (factories != null) {
for (final ICodegenDisplayFactory factory : factories) {
final ICodegenComposite composite = factory.createComposite(parent, style, toolkit);
if (codegen != null) {
codegens.add(composite);
}
}
}
if (codegens.size() == 0) {
codegens.add(this.defaultFactory.createComposite(parent, style, toolkit));
}
return codegens.toArray(new ICodegenComposite[codegens.size()]);
}
/**
* This method should return the same factories that was used to create the Wizard pages & Composites from
* findCompositeByGeneratorId and findPageByGeneratorId since the factories are kept within a map generated
* from the start.
*/
@Override
public List<ICodegenDisplayFactory> findCodegenDisplayFactoriesByGeneratorId(final String codegen) {
final List<ICodegenDisplayFactory> factories = this.codegenToWizardMap.get(codegen);
return factories;
}
@Override
public ICodegenWizardPage getDefaultPage() {
return this.defaultFactory.createPage();
}
}