blob: 5f5b050650ea3b35e57b02f28fde33b9279dcadb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 - 2006 University Of British Columbia 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:
* University Of British Columbia - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.bugzilla.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Quick config rdf parser.
*
* <pre>
* config.cgi?ctype=rdf
* </pre>
*
* Populates a <link>ProductConfiguration</link> data structure.
*
* @author Rob Elves
*/
public class SaxConfigurationContentHandler extends DefaultHandler {
private static final String ELEMENT_RESOLUTION = "resolution";
private static final String ELEMENT_STATUS_OPEN = "status_open";
private static final String ELEMENT_TARGET_MILESTONE = "target_milestone";
private static final String ELEMENT_TARGET_MILESTONES = "target_milestones";
private static final String ELEMENT_INSTALL_VERSION = "install_version";
private static final String ATTRIBUTE_RDF_ABOUT = "rdf:about";
private static final String ATTRIBUTE_RESOURCE = "resource";
private static final String ELEMENT_VERSION = "version";
private static final String ELEMENT_VERSIONS = "versions";
private static final String ELEMENT_COMPONENT = "component";
private static final String ELEMENT_COMPONENTS = "components";
private static final String ELEMENT_NAME = "name";
private static final String ELEMENT_PRODUCTS = "products";
private static final String ELEMENT_SEVERITY = "severity";
private static final String ELEMENT_PRIORITY = "priority";
private static final String ELEMENT_KEYWORD = "keyword";
private static final String ELEMENT_OP_SYS = "op_sys";
private static final String ELEMENT_PLATFORM = "platform";
private static final String ELEMENT_LI = "li";
private static final String ELEMENT_STATUS = "status";
private static final int EXPECTING_ROOT = 0;
private static final int IN_INSTALL_VERSION = 1 << 1;
private static final int IN_STATUS = 1 << 2;
private static final int IN_PLATFORM = 1 << 3;
private static final int IN_OP_SYS = 1 << 4;
private static final int IN_PRIORITY = 1 << 5;
private static final int IN_SEVERITY = 1 << 6;
private static final int IN_PRODUCTS = 1 << 7;
private static final int IN_COMPONENTS = 1 << 8;
private static final int IN_VERSIONS = 1 << 9;
private static final int IN_LI = 1 << 10;
private static final int IN_LI_LI = 1 << 11;
private static final int IN_NAME = 1 << 12;
private static final int IN_COMPONENT = 1 << 13;
private static final int IN_VERSION = 1 << 14;
private static final int IN_TARGET_MILESTONES = 1 << 15;
private static final int IN_TARGET_MILESTONE = 1 << 16;
private static final int IN_STATUS_OPEN = 1 << 17;
private static final int IN_RESOLUTION = 1 << 18;
private static final int IN_KEYWORD = 1 << 19;
private static final int IN_STATUS_CLOSED = 1 << 20;
private int state = EXPECTING_ROOT;
private StringBuffer currentProduct = new StringBuffer();
private StringBuffer parsedValue = new StringBuffer();
private String about;
private RepositoryConfiguration configuration = new RepositoryConfiguration();
private Map<String, List<String>> components = new HashMap<String, List<String>>();
private Map<String, List<String>> versions = new HashMap<String, List<String>>();
private Map<String, List<String>> milestones = new HashMap<String, List<String>>();
private Map<String, StringBuffer> componentNames = new HashMap<String, StringBuffer>();
private Map<String, StringBuffer> versionNames = new HashMap<String, StringBuffer>();
private Map<String, StringBuffer> milestoneNames = new HashMap<String, StringBuffer>();
public RepositoryConfiguration getConfiguration() {
return configuration;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
switch (state) {
case IN_PRODUCTS | IN_LI | IN_NAME:
currentProduct.append(String.copyValueOf(ch, start, length));
break;
case IN_COMPONENTS | IN_LI | IN_COMPONENT | IN_NAME:
String comp = String.copyValueOf(ch, start, length);
if (about != null) {
StringBuffer name = componentNames.get(about);
if (name == null) {
name = new StringBuffer();
componentNames.put(about, name);
}
name.append(comp);
}
break;
case IN_VERSIONS | IN_LI | IN_VERSION | IN_NAME:
String ver = String.copyValueOf(ch, start, length);
if (about != null) {
StringBuffer name = versionNames.get(about);
if (name == null) {
name = new StringBuffer();
versionNames.put(about, name);
}
name.append(ver);
}
break;
case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE | IN_NAME:
String target = String.copyValueOf(ch, start, length);
if (about != null) {
StringBuffer name = milestoneNames.get(about);
if (name == null) {
name = new StringBuffer();
milestoneNames.put(about, name);
}
name.append(target);
}
break;
case IN_PLATFORM | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_OP_SYS | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_PRIORITY | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_SEVERITY | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_INSTALL_VERSION:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_STATUS | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_RESOLUTION | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_KEYWORD | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
case IN_STATUS_OPEN | IN_LI:
parsedValue.append(String.copyValueOf(ch, start, length));
break;
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals(ELEMENT_STATUS)) {
state = state | IN_STATUS;
} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) == IN_LI)) {
state = state | IN_LI_LI;
parseResource(attributes);
} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) != IN_LI)) {
state = state | IN_LI;
} else if (localName.equals(ELEMENT_PLATFORM)) {
state = state | IN_PLATFORM;
} else if (localName.equals(ELEMENT_OP_SYS)) {
state = state | IN_OP_SYS;
} else if (localName.equals(ELEMENT_PRIORITY)) {
state = state | IN_PRIORITY;
} else if (localName.equals(ELEMENT_SEVERITY)) {
state = state | IN_SEVERITY;
} else if (localName.equals(ELEMENT_PRODUCTS)) {
state = state | IN_PRODUCTS;
} else if (localName.equals(ELEMENT_OP_SYS)) {
state = state | IN_OP_SYS;
} else if (localName.equals(ELEMENT_NAME)) {
state = state | IN_NAME;
currentProduct = new StringBuffer();
} else if (localName.equals(ELEMENT_COMPONENTS)) {
state = state | IN_COMPONENTS;
} else if (localName.equals(ELEMENT_COMPONENT)) {
state = state | IN_COMPONENT;
parseResource(attributes);
} else if (localName.equals(ELEMENT_VERSIONS)) {
state = state | IN_VERSIONS;
} else if (localName.equals(ELEMENT_VERSION)) {
state = state | IN_VERSION;
parseResource(attributes);
} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
state = state | IN_INSTALL_VERSION;
} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
state = state | IN_TARGET_MILESTONES;
} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
state = state | IN_TARGET_MILESTONE;
parseResource(attributes);
} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
state = state | IN_STATUS_OPEN;
} else if (localName.equals(ELEMENT_RESOLUTION)) {
state = state | IN_RESOLUTION;
} else if (localName.equals(ELEMENT_KEYWORD)) {
state = state | IN_KEYWORD;
}
parsedValue = new StringBuffer();
}
private void parseResource(Attributes attributes) {
switch (state) {
case IN_PRODUCTS | IN_LI | IN_COMPONENTS | IN_LI_LI:
if (attributes != null) {
String compURI = attributes.getValue(ATTRIBUTE_RESOURCE);
if (compURI != null && currentProduct.length() > 0) {
List<String> compURIs = components.get(currentProduct.toString());
if (compURIs == null) {
compURIs = new ArrayList<String>();
components.put(currentProduct.toString(), compURIs);
}
compURIs.add(compURI);
}
}
break;
case IN_PRODUCTS | IN_LI | IN_VERSIONS | IN_LI_LI:
if (attributes != null) {
String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
if (resourceURI != null && currentProduct.length() > 0) {
List<String> versionUris = versions.get(currentProduct.toString());
if (versionUris == null) {
versionUris = new ArrayList<String>();
versions.put(currentProduct.toString(), versionUris);
}
versionUris.add(resourceURI);
}
}
break;
case IN_PRODUCTS | IN_LI | IN_TARGET_MILESTONES | IN_LI_LI:
if (attributes != null) {
String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
if (resourceURI != null) {
List<String> milestoneUris = milestones.get(currentProduct.toString());
if (milestoneUris == null) {
milestoneUris = new ArrayList<String>();
milestones.put(currentProduct.toString(), milestoneUris);
}
milestoneUris.add(resourceURI);
}
}
break;
case IN_COMPONENTS | IN_LI | IN_COMPONENT:
if (attributes != null) {
about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
}
break;
case IN_VERSIONS | IN_LI | IN_VERSION:
if (attributes != null) {
about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
}
break;
case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE:
if (attributes != null) {
about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
}
break;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// KEEP: && ((state & IN_LI) == IN_LI)
if (localName.equals(ELEMENT_STATUS)) {
state = state & ~IN_STATUS;
} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) == IN_LI_LI)) {
state = state & ~IN_LI_LI;
} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) != IN_LI_LI)) {
state = state & ~IN_LI;
if (parsedValue.length() == 0)
return;
if (state == (IN_STATUS)) {
configuration.addStatus(parsedValue.toString());
} else if (state == (IN_STATUS_OPEN)) {
configuration.addOpenStatusValue(parsedValue.toString());
} else if (state == (IN_STATUS_CLOSED)) {
// TODO: Add closed status values to configuration
} else if (state == (IN_RESOLUTION)) {
configuration.addResolution(parsedValue.toString());
} else if (state == (IN_KEYWORD)) {
configuration.addKeyword(parsedValue.toString());
} else if (state == (IN_PLATFORM)) {
configuration.addPlatform(parsedValue.toString());
} else if (state == (IN_OP_SYS)) {
configuration.addOS(parsedValue.toString());
} else if (state == (IN_PRIORITY)) {
configuration.addPriority(parsedValue.toString());
} else if (state == (IN_SEVERITY)) {
configuration.addSeverity(parsedValue.toString());
}
} else if (localName.equals(ELEMENT_PLATFORM)) {
state = state & ~IN_PLATFORM;
} else if (localName.equals(ELEMENT_OP_SYS)) {
state = state & ~IN_OP_SYS;
} else if (localName.equals(ELEMENT_PRIORITY)) {
state = state & ~IN_PRIORITY;
} else if (localName.equals(ELEMENT_SEVERITY)) {
state = state & ~IN_SEVERITY;
} else if (localName.equals(ELEMENT_PRODUCTS)) {
state = state & ~IN_PRODUCTS;
} else if (localName.equals(ELEMENT_OP_SYS)) {
state = state & ~IN_OP_SYS;
} else if (localName.equals(ELEMENT_NAME)) {
state = state & ~IN_NAME;
if (state == (IN_PRODUCTS | IN_LI) && currentProduct.length() > 0) {
configuration.addProduct(currentProduct.toString());
}
} else if (localName.equals(ELEMENT_COMPONENTS)) {
state = state & ~IN_COMPONENTS;
} else if (localName.equals(ELEMENT_COMPONENT)) {
state = state & ~IN_COMPONENT;
} else if (localName.equals(ELEMENT_VERSION)) {
state = state & ~IN_VERSION;
} else if (localName.equals(ELEMENT_VERSIONS)) {
state = state & ~IN_VERSIONS;
} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
state = state & ~IN_INSTALL_VERSION;
configuration.setInstallVersion(parsedValue.toString());
} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
state = state & ~IN_TARGET_MILESTONE;
} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
state = state & ~IN_TARGET_MILESTONES;
} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
state = state & ~IN_STATUS_OPEN;
} else if (localName.equals(ELEMENT_RESOLUTION)) {
state = state & ~IN_RESOLUTION;
} else if (localName.equals(ELEMENT_KEYWORD)) {
state = state & ~IN_KEYWORD;
}
}
@Override
public void endDocument() throws SAXException {
for (String product : components.keySet()) {
List<String> componentURIs = components.get(product);
for (String uri : componentURIs) {
StringBuffer realName = componentNames.get(uri);
if (realName != null && product.length() > 0) {
configuration.addComponent(product, realName.toString());
}
}
}
for (String product : versions.keySet()) {
List<String> versionURIs = versions.get(product);
for (String uri : versionURIs) {
StringBuffer realName = versionNames.get(uri);
if (realName != null) {
configuration.addVersion(product, realName.toString());
}
}
}
for (String product : milestones.keySet()) {
List<String> milestoneURIs = milestones.get(product);
for (String uri : milestoneURIs) {
StringBuffer realName = milestoneNames.get(uri);
if (realName != null) {
configuration.addTargetMilestone(product, realName.toString());
}
}
}
super.endDocument();
}
}