blob: 5cdca3a03956de36abe4666e7f5ff947ca4cadd1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.registry;
import java.util.*;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.internal.runtime.Policy;
import org.eclipse.core.runtime.*;
import org.osgi.framework.Bundle;
/**
* An object which represents the user-defined contents of an extension
* in a plug-in manifest.
* <p>
* This class may be instantiated, or further subclassed.
* </p>
*/
public class ConfigurationElement extends NestedRegistryModelObject implements IConfigurationElement {
int PLUGIN_ERROR = 1;
// DTD properties (included in plug-in manifest)
private String value = null;
private ConfigurationProperty[] properties = null;
private IConfigurationElement[] children = null;
public Object createExecutableExtension(String attributeName) throws CoreException {
String prop = null;
String executable;
String pluginName = null;
String className = null;
Object initData = null;
int i;
if (attributeName != null)
prop = getAttribute(attributeName);
else {
// property not specified, try as element value
prop = getValue();
if (prop != null) {
prop = prop.trim();
if (prop.equals("")) //$NON-NLS-1$
prop = null;
}
}
if (prop == null) {
// property not defined, try as a child element
IConfigurationElement[] exec;
IConfigurationElement[] parms;
IConfigurationElement element;
Hashtable initParms;
String pname;
exec = getChildren(attributeName);
if (exec.length != 0) {
element = exec[0]; // assumes single definition
pluginName = element.getAttribute("plugin"); //$NON-NLS-1$
className = element.getAttribute("class"); //$NON-NLS-1$
parms = element.getChildren("parameter"); //$NON-NLS-1$
if (parms != null) {
initParms = new Hashtable(parms.length + 1);
for (i = 0; i < parms.length; i++) {
pname = parms[i].getAttribute("name"); //$NON-NLS-1$
if (pname != null)
initParms.put(pname, parms[i].getAttribute("value")); //$NON-NLS-1$
}
if (!initParms.isEmpty())
initData = initParms;
}
}
// specified name is not a simple attribute nor child element
else {
String message = Policy.bind("plugin.extDefNotFound", attributeName); //$NON-NLS-1$
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, PLUGIN_ERROR, message, null); //$NON-NLS-1$
InternalPlatform.getDefault().getLog(InternalPlatform.getDefault().getBundleContext().getBundle()).log(status); //$NON-NLS-1$
throw new CoreException(status);
}
} else {
// simple property or element value, parse it into its components
i = prop.indexOf(':');
if (i != -1) {
executable = prop.substring(0, i).trim();
initData = prop.substring(i + 1).trim();
} else
executable = prop;
i = executable.indexOf('/');
if (i != -1) {
pluginName = executable.substring(0, i).trim();
className = executable.substring(i + 1).trim();
} else
className = executable;
}
if (className == null || className.equals("")) { //$NON-NLS-1$
String message = Policy.bind("plugin.extDefNoClass", attributeName); //$NON-NLS-1$
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, PLUGIN_ERROR, message, null); //$NON-NLS-1$
InternalPlatform.getDefault().getLog(InternalPlatform.getDefault().getBundleContext().getBundle()).log(status); //$NON-NLS-1$
throw new CoreException(status);
}
return createExecutableExtension(InternalPlatform.getDefault().getBundle(getDeclaringExtension().getNamespace()), pluginName, className, initData, this, attributeName);
}
Object createExecutableExtension(Bundle bundle, String pluginName, String className, Object initData, IConfigurationElement cfig, String propertyName) throws CoreException {
String id = bundle.getSymbolicName(); // this plugin id
// check if we need to delegate to some other plugin
if (pluginName != null && !pluginName.equals("") && !pluginName.equals(id)) { //$NON-NLS-1$
Bundle otherBundle = null;
otherBundle = InternalPlatform.getDefault().getBundle(pluginName);
return createExecutableExtension(otherBundle, className, initData, cfig, propertyName);
}
return createExecutableExtension(bundle, className, initData, cfig, propertyName);
}
public Object createExecutableExtension(Bundle bundle, String className, Object initData, IConfigurationElement cfig, String propertyName) throws CoreException {
// load the requested class from this plugin
Class classInstance = null;
try {
classInstance = bundle.loadClass(className);
} catch (Exception e1) {
throwException(Policy.bind("plugin.loadClassError", bundle.getSymbolicName(), className), e1); //$NON-NLS-1$
} catch (LinkageError e) {
throwException(Policy.bind("plugin.loadClassError", bundle.getSymbolicName(), className), e); //$NON-NLS-1$
}
// create a new instance
Object result = null;
try {
result = classInstance.newInstance();
} catch (Exception e) {
throwException(Policy.bind("plugin.instantiateClassError", bundle.getSymbolicName(), className), e); //$NON-NLS-1$
}
// check if we have extension adapter and initialize
if (result instanceof IExecutableExtension) {
try {
// make the call even if the initialization string is null
((IExecutableExtension) result).setInitializationData(cfig, propertyName, initData);
} catch (CoreException ce) {
// user code threw exception
InternalPlatform.getDefault().getLog(InternalPlatform.getDefault().getBundleContext().getBundle()).log(ce.getStatus());
throw new CoreException(ce.getStatus());
} catch (Exception te) {
// user code caused exception
throwException(Policy.bind("policy.initObjectError", bundle.getSymbolicName(), className), te); //$NON-NLS-1$
}
}
return result;
}
private void throwException(String message, Throwable exception) throws CoreException {
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, PLUGIN_ERROR, message, exception);
InternalPlatform.getDefault().getLog(InternalPlatform.getDefault().getBundleContext().getBundle()).log(status);
throw new CoreException(status);
}
/**
* Returns the extension in which this configuration element is declared.
* If this element is a top-level child of an extension, the returned value
* is equivalent to <code>getParent</code>.
*
* @return the extension in which this configuration element is declared
* or <code>null</code>
*/
public Extension getParentExtension() {
Object p = getParent();
while (p != null && p instanceof ConfigurationElement)
p = ((ConfigurationElement) p).getParent();
return (Extension) p;
}
public IExtension getDeclaringExtension() {
return getParentExtension();
}
/**
* Returns the properties associated with this element.
*
* @return the properties associated with this element
* or <code>null</code>
*/
public ConfigurationProperty[] getProperties() {
return properties;
}
/**
* Returns the value of this element.
*
* @return the value of this element or <code>null</code>
*/
public String getValue() {
String s = getValueAsIs();
if (s == null)
return null;
return s;
}
public String getValueAsIs() {
return value;
}
/**
* Returns this element's sub-elements.
*
* @return the sub-elements of this element or <code>null</code>
*/
public IConfigurationElement[] getChildren() {
return children == null ? new IConfigurationElement[0] : children;
}
public IConfigurationElement[] getChildren(String name) {
IConfigurationElement[] list = getChildren();
if (list == null)
return new IConfigurationElement[0];
List children = new ArrayList();
for (int i = 0; i < list.length; i++) {
IConfigurationElement element = list[i];
if (name.equals(element.getName()))
children.add(list[i]);
}
return (IConfigurationElement[]) children.toArray(new IConfigurationElement[children.size()]);
}
public String getAttribute(String name) {
ConfigurationProperty[] list = getProperties();
if (list == null)
return null;
ConfigurationProperty found = null;
for (int i = 0; i < list.length; i++)
if (name.equals(list[i].getName())) {
found = list[i];
break;
}
return found == null ? null : found.getValue();
}
public String getAttributeAsIs(String name) {
ConfigurationProperty[] list = getProperties();
if (list == null)
return null;
for (int i = 0; i < list.length; i++)
if (name.equals(list[i].getName()))
return list[i].getValue();
return null;
}
public String[] getAttributeNames() {
ConfigurationProperty[] list = getProperties();
if (list == null)
return new String[0];
String[] result = new String[list.length];
for (int i = 0; i < list.length; i++)
result[i] = list[i].getName();
return result;
}
/**
* Sets the properties associated with this element.
*
* @param value the properties to associate with this element. May be <code>null</code>.
*/
public void setProperties(ConfigurationProperty[] value) {
properties = value;
}
/**
* Sets configuration elements contained by this element
*
* @param value the configuration elements to be associated with this element.
* May be <code>null</code>.
*/
public void setChildren(IConfigurationElement[] value) {
children = value;
}
/**
* Sets the value of this element.
*
* @param value the new value of this element. May be <code>null</code>.
*/
public void setValue(String value) {
this.value = value;
}
/**
* Optimization to replace a non-localized key with its localized value. Avoids having
* to access resource bundles for further lookups.
*/
public void setLocalizedValue(String value) {
this.value = value;
((ExtensionRegistry) InternalPlatform.getDefault().getRegistry()).setDirty(true);
}
}