/******************************************************************************* * Copyright (c) 2012 Tilera Corporation and others. * 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 * * Contributors: * William R. Swanson (Tilera Corporation) *******************************************************************************/ package org.eclipse.cdt.visualizer.core; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import javax.lang.model.type.NullType; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IContributor; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; // --------------------------------------------------------------------------- // ExtensionElement // --------------------------------------------------------------------------- /** Facade/utility class for dealing with Eclipse extensions. */ public class ExtensionElement { // --- static methods --- /** Wraps list of raw extension declarations. */ public static List<ExtensionElement> wrapExtensionElements(IConfigurationElement[] elements) { int count = (elements == null) ? 0 : elements.length; List<ExtensionElement> result = new ArrayList<ExtensionElement>(count); for (int i=0; i<count; ++i) { result.add(new ExtensionElement(elements[i])); } return result; } // --- members --- /** Actual extension description loaded from extension point. */ protected IConfigurationElement m_element = null; // --- constructors/destructors --- /** Constructor. */ public ExtensionElement(IConfigurationElement element) { m_element = element; } // --- methods --- /** Gets string value of specified attribute. */ public String getAttribute(String attributeName) { return m_element.getAttribute(attributeName); } /** Creates and returns instance of implementing class, using class name found in "class" attribute. */ public <T> T getClassAttribute() { return getClassAttribute("class"); } /** Creates and returns instance of implementing class, using class name found in specified attribute. */ @SuppressWarnings("unchecked") public <T> T getClassAttribute(String attributeName) { T result = null; try { // TODO: Hmm... is there a right way to do this, without an unchecked cast? result = (T) m_element.createExecutableExtension(attributeName); } catch (ClassCastException ex) { // For now, eat it, and don't return this extension. // TODO: decide how to log this } catch (CoreException ex) { // For now, eat it, and don't return this extension. // TODO: decide how to log this } return result; } /** Creates and returns instance of implementing class, using class name found in specified attribute. */ @SuppressWarnings("unchecked") public <T> T getClassAttribute(String attributeName, Object... arguments) { // Make sure we default to zero-argument form if we can. if (arguments == null || arguments.length == 0) return getClassAttribute(attributeName); // If we have arguments, have to do a little extra work. T result = null; try { // Get name of class we're trying to load from attribute. String className = getAttribute(attributeName); // Attempt to load class using the source plugin's class loader. // TODO: is there a better way? IContributor contributor = m_element.getContributor(); String pluginID = contributor.getName(); Bundle plugin = Platform.getBundle(pluginID); Class<?> instance = plugin.loadClass(className); // Select appropriate constructor for provided argument(s). int argumentsLength = (arguments == null) ? 0 : arguments.length; Class<?>[] argumentTypes = new Class<?>[argumentsLength]; for (int i=0; i<argumentsLength; ++i) { argumentTypes[i] = (arguments[i] == null) ? NullType.class : arguments[i].getClass(); } Constructor<?> constructor = (Constructor<?>) instance.getConstructor(argumentTypes); // Invoke the constructor. result = (T) constructor.newInstance(arguments); } catch (ClassNotFoundException ex) { // TODO: decide how to log this } catch (NoSuchMethodException ex) { // TODO: decide how to log this } catch (InvocationTargetException ex) { // TODO: decide how to log this } catch (IllegalAccessException ex) { // TODO: decide how to log this } catch (InstantiationException ex) { // TODO: decide how to log this } catch (ClassCastException ex) { // TODO: decide how to log this } catch (Exception ex) { // TODO: decide how to log this } return result; } /** Returns child elements of this element. */ public List<ExtensionElement> getChildren() { return wrapExtensionElements(m_element.getChildren()); } }