blob: 9f973b9702b5e386e7c4ca4dbfd1896bddca0845 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.registry;
import java.util.Hashtable;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.spi.RegistryContributor;
import org.eclipse.osgi.util.NLS;
/**
* An object which represents the user-defined contents of an extension
* in a plug-in manifest.
*/
public class ConfigurationElement extends RegistryObject {
static final ConfigurationElement[] EMPTY_ARRAY = new ConfigurationElement[0];
//The id of the parent element. It can be a configuration element or an extension
int parentId;
byte parentType; //This value is only interesting when running from cache.
//Store the properties and the value of the configuration element.
//The format is the following:
// [p1, v1, p2, v2, configurationElementValue]
//If the array size is even, there is no "configurationElementValue (ie getValue returns null)".
//The properties and their values are alternated (v1 is the value of p1).
private String[] propertiesAndValue;
//The name of the configuration element
private String name;
//ID of the actual contributor of this element
//This value can be null when the element is loaded from disk and the owner has been uninstalled.
//This happens when the configuration is obtained from a delta containing removed extension.
private String contributorId;
protected ConfigurationElement(ExtensionRegistry registry, boolean persist) {
super(registry, persist);
}
protected ConfigurationElement(int self, String contributorId, String name, String[] propertiesAndValue, int[] children, int extraDataOffset, int parent, byte parentType, ExtensionRegistry registry, boolean persist) {
super(registry, persist);
setObjectId(self);
this.contributorId = contributorId;
this.name = name;
this.propertiesAndValue = propertiesAndValue;
setRawChildren(children);
setExtraDataOffset(extraDataOffset);
parentId = parent;
this.parentType = parentType;
}
void throwException(String message, Throwable exception) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, IRegistryConstants.PLUGIN_ERROR, message, exception));
}
protected String getValue() {
return getValueAsIs();
}
String getValueAsIs() {
if (propertiesAndValue.length != 0 && propertiesAndValue.length % 2 == 1)
return propertiesAndValue[propertiesAndValue.length - 1];
return null;
}
public String getAttribute(String attrName) {
return getAttributeAsIs(attrName);
}
String getAttributeAsIs(String attrName) {
if (propertiesAndValue.length <= 1)
return null;
int size = propertiesAndValue.length - (propertiesAndValue.length % 2);
for (int i = 0; i < size; i += 2) {
if (propertiesAndValue[i].equals(attrName))
return propertiesAndValue[i + 1];
}
return null;
}
protected String[] getAttributeNames() {
if (propertiesAndValue.length <= 1)
return RegistryObjectManager.EMPTY_STRING_ARRAY;
int size = propertiesAndValue.length / 2;
String[] result = new String[size];
for (int i = 0; i < size; i++) {
result[i] = propertiesAndValue[i * 2];
}
return result;
}
void setProperties(String[] value) {
propertiesAndValue = value;
}
protected String[] getPropertiesAndValue() {
return propertiesAndValue;
}
void setValue(String value) {
if (propertiesAndValue.length == 0) {
propertiesAndValue = new String[] {value};
return;
}
if (propertiesAndValue.length % 2 == 1) {
propertiesAndValue[propertiesAndValue.length - 1] = value;
return;
}
String[] newPropertiesAndValue = new String[propertiesAndValue.length + 1];
System.arraycopy(propertiesAndValue, 0, newPropertiesAndValue, 0, propertiesAndValue.length);
newPropertiesAndValue[propertiesAndValue.length] = value;
propertiesAndValue = newPropertiesAndValue;
}
void setContributorId(String id) {
this.contributorId = id;
}
protected String getContributorId() {
return contributorId;
}
public ConfigurationElement[] getChildren(String childrenName) {
if (getRawChildren().length == 0)
return ConfigurationElement.EMPTY_ARRAY;
ConfigurationElement[] result = new ConfigurationElement[1]; //Most of the time there is only one match
int idx = 0;
RegistryObjectManager objectManager = registry.getObjectManager();
for (int i = 0; i < children.length; i++) {
ConfigurationElement toTest = (ConfigurationElement) objectManager.getObject(children[i], noExtraData() ? RegistryObjectManager.CONFIGURATION_ELEMENT : RegistryObjectManager.THIRDLEVEL_CONFIGURATION_ELEMENT);
if (toTest.name.equals(childrenName)) {
if (idx != 0) {
ConfigurationElement[] copy = new ConfigurationElement[result.length + 1];
System.arraycopy(result, 0, copy, 0, result.length);
result = copy;
}
result[idx++] = toTest;
}
}
if (idx == 0)
result = ConfigurationElement.EMPTY_ARRAY;
return result;
}
void setParentId(int objectId) {
parentId = objectId;
}
protected String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
void setParentType(byte type) {
parentType = type;
}
public IContributor getContributor() {
return registry.getObjectManager().getContributor(contributorId);
}
protected Object createExecutableExtension(String attributeName) throws CoreException {
String prop = null;
String executable;
String contributorName = 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
ConfigurationElement[] exec;
ConfigurationElement[] parms;
ConfigurationElement element;
Hashtable initParms;
String pname;
exec = getChildren(attributeName);
if (exec.length != 0) {
element = exec[0]; // assumes single definition
contributorName = element.getAttribute("plugin"); //$NON-NLS-1$
className = element.getAttribute("class"); //$NON-NLS-1$
parms = element.getChildren("parameter"); //$NON-NLS-1$
if (parms.length != 0) {
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;
}
} else {
// specified name is not a simple attribute nor child element
throwException(NLS.bind(RegistryMessages.exExt_extDefNotFound, attributeName), null);
}
} 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) {
contributorName = executable.substring(0, i).trim();
className = executable.substring(i + 1).trim();
} else
className = executable;
}
// create a new instance
RegistryContributor defaultContributor = registry.getObjectManager().getContributor(contributorId);
Object result = registry.createExecutableExtension(defaultContributor, className, contributorName);
// Check if we have extension adapter and initialize;
// Make the call even if the initialization string is null
try {
// We need to take into account both "old" and "new" style executable extensions
ConfigurationElementHandle confElementHandle = new ConfigurationElementHandle(registry.getObjectManager(), getObjectId());
if (result instanceof IExecutableExtension)
((IExecutableExtension) result).setInitializationData(confElementHandle, attributeName, initData);
} catch (CoreException ce) {
// user code threw exception
throw ce;
} catch (Exception te) {
// user code caused exception
throwException(NLS.bind(RegistryMessages.plugin_initObjectError, getContributor().getName(), className), te);
}
// Deal with executable extension factories.
if (result instanceof IExecutableExtensionFactory)
result = ((IExecutableExtensionFactory) result).create();
return result;
}
}