blob: e98d7cc2f42e37b1118fa579c5b528c92a0b0955 [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.model;
import java.util.*;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.internal.runtime.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.model.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.ServiceReference;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
public class PluginParser extends DefaultHandler implements IModel {
// concrete object factory
Factory factory;
// File name for this plugin or fragment
// This to help with error reporting
String locationName = null;
// Current State Information
Stack stateStack = new Stack();
// Current object stack (used to hold the current object we are
// populating in this plugin descriptor
Stack objectStack = new Stack();
Locator locator = null;
// Valid States
private static final int IGNORED_ELEMENT_STATE = 0;
private static final int INITIAL_STATE = 1;
private static final int PLUGIN_STATE = 2;
private static final int PLUGIN_RUNTIME_STATE = 3;
private static final int PLUGIN_REQUIRES_STATE = 4;
private static final int PLUGIN_EXTENSION_POINT_STATE = 5;
private static final int PLUGIN_EXTENSION_STATE = 6;
private static final int RUNTIME_LIBRARY_STATE = 7;
private static final int LIBRARY_EXPORT_STATE = 8;
// private static final int LIBRARY_PACKAGES_STATE = 12;
private static final int PLUGIN_REQUIRES_IMPORT_STATE = 9;
private static final int CONFIGURATION_ELEMENT_STATE = 10;
private static final int FRAGMENT_STATE = 11;
// Keep a group of vectors as a temporary scratch space. These
// vectors will be used to populate arrays in the plugin descriptor
// once processing of the XML file is complete.
private static final int EXTENSION_POINT_INDEX = 0;
private static final int EXTENSION_INDEX = 1;
private static final int LAST_INDEX = 1;
private Vector scratchVectors[] = new Vector[LAST_INDEX + 1];
private ServiceReference parserReference;
public PluginParser(Factory factory) {
super();
this.factory = factory;
}
/**
* Receive a Locator object for document events.
*
* <p>By default, do nothing. Application writers may override this
* method in a subclass if they wish to store the locator for use
* with other document events.</p>
*
* @param locator A locator for all SAX document events.
* @see org.xml.sax.ContentHandler#setDocumentLocator
* @see org.xml.sax.Locator
*/
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
public void characters(char[] ch, int start, int length) {
int state = ((Integer) stateStack.peek()).intValue();
if (state != CONFIGURATION_ELEMENT_STATE)
return;
if (state == CONFIGURATION_ELEMENT_STATE) {
// Accept character data within an element, is when it is
// part of a configuration element (i.e. an element within an EXTENSION element
ConfigurationElementModel currentConfigElement = (ConfigurationElementModel) objectStack.peek();
String value = new String(ch, start, length);
String oldValue = currentConfigElement.getValueAsIs();
if (oldValue == null) {
if (value.trim().length() != 0)
currentConfigElement.setValue(value);
} else {
currentConfigElement.setValue(oldValue + value);
}
}
}
public void endDocument() {
}
public void endElement(String uri, String elementName, String qName) {
switch (((Integer) stateStack.peek()).intValue()) {
case IGNORED_ELEMENT_STATE :
stateStack.pop();
break;
case INITIAL_STATE :
// shouldn't get here
internalError(NLS.bind(Messages.parse_internalStack, elementName));
break;
case PLUGIN_STATE :
case FRAGMENT_STATE :
if (elementName.equals(PLUGIN) || elementName.equals(FRAGMENT)) {
stateStack.pop();
PluginModel root = (PluginModel) objectStack.peek();
// Put the extension points into this plugin
Vector extPointVector = scratchVectors[EXTENSION_POINT_INDEX];
if (extPointVector.size() > 0) {
root.setDeclaredExtensionPoints((ExtensionPointModel[]) extPointVector.toArray(new ExtensionPointModel[extPointVector.size()]));
scratchVectors[EXTENSION_POINT_INDEX].removeAllElements();
}
// Put the extensions into this plugin too
Vector extVector = scratchVectors[EXTENSION_INDEX];
if (extVector.size() > 0) {
root.setDeclaredExtensions((ExtensionModel[]) extVector.toArray(new ExtensionModel[extVector.size()]));
scratchVectors[EXTENSION_INDEX].removeAllElements();
}
}
break;
case PLUGIN_RUNTIME_STATE :
if (elementName.equals(RUNTIME)) {
stateStack.pop();
// take the vector of library entries and put them into the plugin
// descriptor
Vector libVector = (Vector) objectStack.pop();
if (libVector.size() > 0) {
PluginModel model = (PluginModel) objectStack.peek();
model.setRuntime((LibraryModel[]) libVector.toArray(new LibraryModel[libVector.size()]));
}
}
break;
case PLUGIN_REQUIRES_STATE :
if (elementName.equals(PLUGIN_REQUIRES)) {
stateStack.pop();
// take the vector of prerequisites and put them into the plugin
// descriptor
Vector importVector = (Vector) objectStack.pop();
if (importVector.size() > 0) {
PluginModel parentDescriptor = (PluginModel) objectStack.peek();
parentDescriptor.setRequires((PluginPrerequisiteModel[]) importVector.toArray(new PluginPrerequisiteModel[importVector.size()]));
}
}
break;
case PLUGIN_EXTENSION_POINT_STATE :
if (elementName.equals(EXTENSION_POINT)) {
stateStack.pop();
}
break;
case PLUGIN_EXTENSION_STATE :
if (elementName.equals(EXTENSION)) {
stateStack.pop();
// Finish up extension object
ExtensionModel currentExtension = (ExtensionModel) objectStack.pop();
PluginModel parent = (PluginModel) objectStack.peek();
currentExtension.setParent(parent);
scratchVectors[EXTENSION_INDEX].addElement(currentExtension);
}
break;
case RUNTIME_LIBRARY_STATE :
if (elementName.equals(LIBRARY)) {
LibraryModel curLibrary = (LibraryModel) objectStack.pop();
// Clean up the exports for this library entry
Vector exportsVector = (Vector) objectStack.pop();
if (exportsVector.size() > 0) {
curLibrary.setExports((String[]) exportsVector.toArray(new String[exportsVector.size()]));
}
// Add this library element to the vector "runtime" on the stack
Vector libraryVector = (Vector) objectStack.peek();
libraryVector.addElement(curLibrary);
stateStack.pop();
}
break;
case LIBRARY_EXPORT_STATE :
if (elementName.equals(LIBRARY_EXPORT)) {
stateStack.pop();
}
break;
case PLUGIN_REQUIRES_IMPORT_STATE :
if (elementName.equals(PLUGIN_REQUIRES_IMPORT)) {
stateStack.pop();
}
break;
case CONFIGURATION_ELEMENT_STATE :
// We don't care what the element name was
stateStack.pop();
// Now finish up the configuration element object
ConfigurationElementModel currentConfigElement = (ConfigurationElementModel) objectStack.pop();
String value = currentConfigElement.getValueAsIs();
if (value != null) {
currentConfigElement.setValue(value.trim());
}
Object parent = objectStack.peek();
currentConfigElement.setParent(parent);
if (((Integer) stateStack.peek()).intValue() == PLUGIN_EXTENSION_STATE) {
// Want to add this configuration element to the subelements of an extension
ConfigurationElementModel[] oldValues = (ConfigurationElementModel[]) ((ExtensionModel) parent).getSubElements();
int size = (oldValues == null) ? 0 : oldValues.length;
ConfigurationElementModel[] newValues = new ConfigurationElementModel[size + 1];
for (int i = 0; i < size; i++) {
newValues[i] = oldValues[i];
}
newValues[size] = currentConfigElement;
((ExtensionModel) parent).setSubElements(newValues);
} else {
ConfigurationElementModel[] oldValues = (ConfigurationElementModel[]) ((ConfigurationElementModel) parent).getSubElements();
int size = (oldValues == null) ? 0 : oldValues.length;
ConfigurationElementModel[] newValues = new ConfigurationElementModel[size + 1];
for (int i = 0; i < size; i++) {
newValues[i] = oldValues[i];
}
newValues[size] = currentConfigElement;
((ConfigurationElementModel) parent).setSubElements(newValues);
}
break;
}
}
public void error(SAXParseException ex) {
logStatus(ex);
}
public void fatalError(SAXParseException ex) throws SAXException {
logStatus(ex);
throw ex;
}
public void handleExtensionPointState(String elementName, Attributes attributes) {
// We ignore all elements under extension points (if there are any)
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, EXTENSION_POINT, elementName));
}
public void handleExtensionState(String elementName, Attributes attributes) {
// You need to change the state here even though we will be executing the same
// code for ExtensionState and ConfigurationElementState. We ignore the name
// of the element for ConfigurationElements. When we are wrapping up, we will
// want to add each configuration element object to the subElements vector of
// its parent configuration element object. However, the first configuration
// element object we created (the last one we pop off the stack) will need to
// be added to a vector in the extension object called _configuration.
stateStack.push(new Integer(CONFIGURATION_ELEMENT_STATE));
// create a new Configuration Element and push it onto the object stack
ConfigurationElementModel currentConfigurationElement = factory.createConfigurationElement();
objectStack.push(currentConfigurationElement);
currentConfigurationElement.setName(elementName);
// Processing the attributes of a configuration element involves creating
// a new configuration property for each attribute and populating the configuration
// property with the name/value pair of the attribute. Note there will be one
// configuration property for each attribute
parseConfigurationElementAttributes(attributes);
}
public void handleInitialState(String elementName, Attributes attributes) {
if (elementName.equals(PLUGIN)) {
stateStack.push(new Integer(PLUGIN_STATE));
parsePluginAttributes(attributes);
} else if (elementName.equals(FRAGMENT)) {
stateStack.push(new Integer(FRAGMENT_STATE));
parseFragmentAttributes(attributes);
} else {
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownTopElement, elementName));
}
}
public void handleLibraryExportState(String elementName, Attributes attributes) {
// All elements ignored.
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, LIBRARY_EXPORT, elementName));
}
public void handleLibraryState(String elementName, Attributes attributes) {
if (elementName.equals(LIBRARY_EXPORT)) {
// Change State
stateStack.push(new Integer(LIBRARY_EXPORT_STATE));
// The top element on the stack much be a library element
LibraryModel currentLib = (LibraryModel) objectStack.peek();
if (attributes == null)
return;
String maskValue = null;
// Process Attributes
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(LIBRARY_EXPORT_MASK))
maskValue = attrValue;
else
internalError(NLS.bind(Messages.parse_unknownAttribute, LIBRARY, attrName));
}
// set up mask tables
// pop off the library - already in currentLib
objectStack.pop();
Vector exportMask = (Vector) objectStack.peek();
// push library back on
objectStack.push(currentLib);
if ((maskValue != null) && (!exportMask.contains(maskValue)))
exportMask.addElement(maskValue);
return;
}
if (elementName.equals(LIBRARY_PACKAGES)) {
LibraryModel currentLib = (LibraryModel) objectStack.peek();
if (attributes == null)
return;
for (int i = 0; i < attributes.getLength(); i++) {
if (LIBRARY_PACKAGES_PREFIXES.equals(attributes.getLocalName(i))) {
String line = attributes.getValue(i);
String[] prefixes = getArrayFromList(line);
currentLib.setPackagePrefixes(prefixes);
}
}
return;
}
// Any other element is invalid
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, LIBRARY, elementName));
return;
}
/**
* convert a list of comma-separated tokens into an array
*/
protected static String[] getArrayFromList(String line) {
if (line == null || line.trim().length() == 0)
return null;
Vector list = new Vector();
StringTokenizer tokens = new StringTokenizer(line, ","); //$NON-NLS-1$
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken().trim();
if (token.length() != 0)
list.addElement(token);
}
return list.isEmpty() ? null : (String[]) list.toArray(new String[0]);
}
public void handlePluginState(String elementName, Attributes attributes) {
if (elementName.equals(RUNTIME)) {
// We should only have one Runtime element in a plugin or fragment
Object whatIsIt = objectStack.peek();
if (((whatIsIt instanceof PluginDescriptorModel) && (((PluginDescriptorModel) objectStack.peek()).getRuntime() != null)) || ((whatIsIt instanceof PluginFragmentModel) && (((PluginFragmentModel) objectStack.peek()).getRuntime() != null))) {
// This is at least the 2nd Runtime element we have
// hit. Ignore it and give an error.
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
return;
}
stateStack.push(new Integer(PLUGIN_RUNTIME_STATE));
// Push a new vector to hold all the library entries
objectStack.push(new Vector());
return;
}
if (elementName.equals(PLUGIN_REQUIRES)) {
stateStack.push(new Integer(PLUGIN_REQUIRES_STATE));
// Push a new vector to hold all the prerequisites
objectStack.push(new Vector());
parseRequiresAttributes(attributes);
return;
}
if (elementName.equals(EXTENSION_POINT)) {
stateStack.push(new Integer(PLUGIN_EXTENSION_POINT_STATE));
parseExtensionPointAttributes(attributes);
return;
}
if (elementName.equals(EXTENSION)) {
stateStack.push(new Integer(PLUGIN_EXTENSION_STATE));
parseExtensionAttributes(attributes);
return;
}
// If we get to this point, the element name is one we don't currently accept.
// Set the state to indicate that this element will be ignored
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, PLUGIN + " / " + FRAGMENT, elementName)); //$NON-NLS-1$
}
public void handleRequiresImportState(String elementName, Attributes attributes) {
// All elements ignored.
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, PLUGIN_REQUIRES_IMPORT, elementName));
}
public void handleRequiresState(String elementName, Attributes attributes) {
if (elementName.equals(PLUGIN_REQUIRES_IMPORT)) {
parsePluginRequiresImport(attributes);
return;
}
// If we get to this point, the element name is one we don't currently accept.
// Set the state to indicate that this element will be ignored
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, PLUGIN_REQUIRES, elementName));
}
public void handleRuntimeState(String elementName, Attributes attributes) {
if (elementName.equals(LIBRARY)) {
// Change State
stateStack.push(new Integer(RUNTIME_LIBRARY_STATE));
// Process library attributes
parseLibraryAttributes(attributes);
return;
}
// If we get to this point, the element name is one we don't currently accept.
// Set the state to indicate that this element will be ignored
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownElement, RUNTIME, elementName));
}
public void ignoreableWhitespace(char[] ch, int start, int length) {
}
private void logStatus(SAXParseException ex) {
String name = ex.getSystemId();
if (name == null)
name = locationName;
if (name == null)
name = ""; //$NON-NLS-1$
else
name = name.substring(1 + name.lastIndexOf("/")); //$NON-NLS-1$
String msg;
if (name.equals("")) //$NON-NLS-1$
msg = NLS.bind(Messages.parse_error, ex.getMessage());
else
msg = NLS.bind(Messages.parse_errorNameLineColumn, (new String[] {name, Integer.toString(ex.getLineNumber()), Integer.toString(ex.getColumnNumber()), ex.getMessage()}));
factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, msg, ex));
}
synchronized public PluginModel parsePlugin(InputSource in) throws Exception {
SAXParserFactory factory = acquireXMLParsing();
if (factory == null)
return null; // TODO we log an error
try {
locationName = in.getSystemId();
factory.setNamespaceAware(true);
factory.setNamespaceAware(true);
try {
factory.setFeature("http://xml.org/sax/features/string-interning", true); //$NON-NLS-1$
} catch (SAXException se) {
// ignore; we can still operate without string-interning
}
factory.setValidating(false);
factory.newSAXParser().parse(in, this);
return (PluginModel) objectStack.pop();
} finally {
releaseXMLParsing();
}
}
private SAXParserFactory acquireXMLParsing() {
parserReference = InternalPlatform.getDefault().getBundleContext().getServiceReference("javax.xml.parsers.SAXParserFactory"); //$NON-NLS-1$
if (parserReference == null)
return null;
return (SAXParserFactory) InternalPlatform.getDefault().getBundleContext().getService(parserReference);
}
private void releaseXMLParsing() {
if (parserReference != null)
InternalPlatform.getDefault().getBundleContext().ungetService(parserReference);
}
public void parseConfigurationElementAttributes(Attributes attributes) {
ConfigurationElementModel parentConfigurationElement = (ConfigurationElementModel) objectStack.peek();
parentConfigurationElement.setStartLine(locator.getLineNumber());
Vector propVector = null;
// process attributes
int len = (attributes != null) ? attributes.getLength() : 0;
if (len == 0)
return;
propVector = new Vector();
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i);
ConfigurationPropertyModel currentConfigurationProperty = factory.createConfigurationProperty();
currentConfigurationProperty.setName(attrName);
currentConfigurationProperty.setValue(attrValue);
propVector.addElement(currentConfigurationProperty);
}
parentConfigurationElement.setProperties((ConfigurationPropertyModel[]) propVector.toArray(new ConfigurationPropertyModel[propVector.size()]));
propVector = null;
}
public void parseExtensionAttributes(Attributes attributes) {
PluginModel parent = (PluginModel) objectStack.peek();
ExtensionModel currentExtension = factory.createExtension();
currentExtension.setStartLine(locator.getLineNumber());
objectStack.push(currentExtension);
// Process Attributes
int len = (attributes != null) ? attributes.getLength() : 0;
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(EXTENSION_NAME))
currentExtension.setName(attrValue);
else if (attrName.equals(EXTENSION_ID))
currentExtension.setId(attrValue);
else if (attrName.equals(EXTENSION_TARGET)) {
// check if point is specified as a simple or qualified name
String targetName;
if (attrValue.lastIndexOf('.') == -1) {
String baseId = parent instanceof PluginDescriptorModel ? parent.getId() : ((PluginFragmentModel) parent).getPlugin();
targetName = baseId + "." + attrValue; //$NON-NLS-1$
} else
targetName = attrValue;
currentExtension.setExtensionPoint(targetName);
} else
internalError(NLS.bind(Messages.parse_unknownAttribute, EXTENSION, attrName));
}
}
public void parseExtensionPointAttributes(Attributes attributes) {
ExtensionPointModel currentExtPoint = factory.createExtensionPoint();
currentExtPoint.setStartLine(locator.getLineNumber());
// Process Attributes
int len = (attributes != null) ? attributes.getLength() : 0;
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(EXTENSION_POINT_NAME))
currentExtPoint.setName(attrValue);
else if (attrName.equals(EXTENSION_POINT_ID))
currentExtPoint.setId(attrValue);
else if (attrName.equals(EXTENSION_POINT_SCHEMA))
currentExtPoint.setSchema(attrValue);
else
internalError(NLS.bind(Messages.parse_unknownAttribute, EXTENSION_POINT, attrName));
}
// currentExtPoint contains a pointer to the parent plugin descriptor.
PluginModel root = (PluginModel) objectStack.peek();
currentExtPoint.setParent(root);
// Now populate the vector just below us on the objectStack with this extension point
scratchVectors[EXTENSION_POINT_INDEX].addElement(currentExtPoint);
}
public void parseFragmentAttributes(Attributes attributes) {
PluginFragmentModel current = factory.createPluginFragment();
current.setStartLine(locator.getLineNumber());
objectStack.push(current);
// process attributes
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(FRAGMENT_ID))
current.setId(attrValue);
else if (attrName.equals(FRAGMENT_NAME))
current.setName(attrValue);
else if (attrName.equals(FRAGMENT_VERSION))
current.setVersion(attrValue);
else if (attrName.equals(FRAGMENT_PROVIDER))
current.setProviderName(attrValue);
else if (attrName.equals(FRAGMENT_PLUGIN_ID))
current.setPlugin(attrValue);
else if (attrName.equals(FRAGMENT_PLUGIN_VERSION))
current.setPluginVersion(attrValue);
else if (attrName.equals(FRAGMENT_PLUGIN_MATCH)) {
if (FRAGMENT_PLUGIN_MATCH_PERFECT.equals(attrValue))
current.setMatch(PluginFragmentModel.FRAGMENT_MATCH_PERFECT);
else if (FRAGMENT_PLUGIN_MATCH_EQUIVALENT.equals(attrValue))
current.setMatch(PluginFragmentModel.FRAGMENT_MATCH_EQUIVALENT);
else if (FRAGMENT_PLUGIN_MATCH_COMPATIBLE.equals(attrValue))
current.setMatch(PluginFragmentModel.FRAGMENT_MATCH_COMPATIBLE);
else if (FRAGMENT_PLUGIN_MATCH_GREATER_OR_EQUAL.equals(attrValue))
current.setMatch(PluginFragmentModel.FRAGMENT_MATCH_GREATER_OR_EQUAL);
else
internalError(NLS.bind(Messages.parse_validMatch, attrValue));
} else
internalError(NLS.bind(Messages.parse_unknownAttribute, FRAGMENT, attrName));
}
}
public void parseLibraryAttributes(Attributes attributes) {
// Push a vector to hold the export mask
objectStack.push(new Vector());
LibraryModel current = factory.createLibrary();
current.setStartLine(locator.getLineNumber());
objectStack.push(current);
// Now the objectStack should contain the following:
// plugin descriptor or fragment (bottom of the stack)
// vector to hold all the library entries
// vector to hold the export mask for this library entry
// this library entry (top of the stack)
// process attributes
int len = (attributes != null) ? attributes.getLength() : 0;
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(LIBRARY_NAME))
current.setName(attrValue);
else if (attrName.equals(LIBRARY_TYPE)) {
attrValue = attrValue.toLowerCase();
if (attrValue.equals(LibraryModel.CODE) || attrValue.equals(LibraryModel.RESOURCE))
current.setType(attrValue.toLowerCase());
else
internalError(NLS.bind(Messages.parse_unknownLibraryType, attrValue, current.getName()));
} else
internalError(NLS.bind(Messages.parse_unknownAttribute, LIBRARY, attrName));
}
}
public void parsePluginAttributes(Attributes attributes) {
PluginDescriptorModel current = factory.createPluginDescriptor();
current.setStartLine(locator.getLineNumber());
objectStack.push(current);
// process attributes
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(PLUGIN_ID))
current.setId(attrValue);
else if (attrName.equals(PLUGIN_NAME))
current.setName(attrValue);
else if (attrName.equals(PLUGIN_VERSION))
current.setVersion(attrValue);
else if (attrName.equals(PLUGIN_VENDOR) || (attrName.equals(PLUGIN_PROVIDER)))
current.setProviderName(attrValue);
else if (attrName.equals(PLUGIN_CLASS))
current.setPluginClass(attrValue);
else
internalError(NLS.bind(Messages.parse_unknownAttribute, PLUGIN, attrName));
}
}
public void parsePluginRequiresImport(Attributes attributes) {
PluginPrerequisiteModel current = factory.createPluginPrerequisite();
current.setStartLine(locator.getLineNumber());
// process attributes
int len = (attributes != null) ? attributes.getLength() : 0;
for (int i = 0; i < len; i++) {
String attrName = attributes.getLocalName(i);
String attrValue = attributes.getValue(i).trim();
if (attrName.equals(PLUGIN_REQUIRES_PLUGIN))
current.setPlugin(attrValue);
else if (attrName.equals(PLUGIN_REQUIRES_PLUGIN_VERSION))
current.setVersion(attrValue);
else if (attrName.equals(PLUGIN_REQUIRES_OPTIONAL))
current.setOptional(TRUE.equalsIgnoreCase(attrValue));
else if (attrName.equals(PLUGIN_REQUIRES_MATCH)) {
if (PLUGIN_REQUIRES_MATCH_PERFECT.equals(attrValue))
current.setMatchByte(PluginPrerequisiteModel.PREREQ_MATCH_PERFECT);
else if ((PLUGIN_REQUIRES_MATCH_EQUIVALENT.equals(attrValue)) || (PLUGIN_REQUIRES_MATCH_EXACT.equals(attrValue)))
current.setMatchByte(PluginPrerequisiteModel.PREREQ_MATCH_EQUIVALENT);
else if (PLUGIN_REQUIRES_MATCH_COMPATIBLE.equals(attrValue))
current.setMatchByte(PluginPrerequisiteModel.PREREQ_MATCH_COMPATIBLE);
else if (PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL.equals(attrValue))
current.setMatchByte(PluginPrerequisiteModel.PREREQ_MATCH_GREATER_OR_EQUAL);
else
internalError(NLS.bind(Messages.parse_validMatch, attrValue));
} else if (attrName.equals(PLUGIN_REQUIRES_EXPORT)) {
if (TRUE.equals(attrValue))
current.setExport(true);
else if (FALSE.equals(attrValue))
current.setExport(false);
else
internalError(NLS.bind(Messages.parse_validExport, attrValue));
} else
internalError(NLS.bind(Messages.parse_unknownAttribute, PLUGIN_REQUIRES_IMPORT, attrName));
}
// Populate the vector of prerequisites with this new element
((Vector) objectStack.peek()).addElement(current);
}
public void parseRequiresAttributes(Attributes attributes) {
}
static String replace(String s, String from, String to) {
String str = s;
int fromLen = from.length();
int toLen = to.length();
int ix = str.indexOf(from);
while (ix != -1) {
str = str.substring(0, ix) + to + str.substring(ix + fromLen);
ix = str.indexOf(from, ix + toLen);
}
return str;
}
public void startDocument() {
stateStack.push(new Integer(INITIAL_STATE));
for (int i = 0; i <= LAST_INDEX; i++) {
scratchVectors[i] = new Vector();
}
}
public void startElement(String uri, String elementName, String qName, Attributes attributes) {
switch (((Integer) stateStack.peek()).intValue()) {
case INITIAL_STATE :
handleInitialState(elementName, attributes);
break;
case FRAGMENT_STATE :
handlePluginState(elementName, attributes);
break;
case PLUGIN_STATE :
handlePluginState(elementName, attributes);
break;
case PLUGIN_RUNTIME_STATE :
handleRuntimeState(elementName, attributes);
break;
case PLUGIN_REQUIRES_STATE :
handleRequiresState(elementName, attributes);
break;
case PLUGIN_EXTENSION_POINT_STATE :
handleExtensionPointState(elementName, attributes);
break;
case PLUGIN_EXTENSION_STATE :
case CONFIGURATION_ELEMENT_STATE :
handleExtensionState(elementName, attributes);
break;
case RUNTIME_LIBRARY_STATE :
handleLibraryState(elementName, attributes);
break;
case LIBRARY_EXPORT_STATE :
handleLibraryExportState(elementName, attributes);
break;
case PLUGIN_REQUIRES_IMPORT_STATE :
handleRequiresImportState(elementName, attributes);
break;
default :
stateStack.push(new Integer(IGNORED_ELEMENT_STATE));
internalError(NLS.bind(Messages.parse_unknownTopElement, elementName));
}
}
public void warning(SAXParseException ex) {
logStatus(ex);
}
private void internalError(String message) {
if (locationName != null)
factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, locationName + ": " + message, null)); //$NON-NLS-1$
else
factory.error(new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, message, null));
}
}