Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.weld.xml.BeansXmlHandler Maven / Gradle / Ivy
package org.jboss.weld.xml;
import static java.util.Arrays.asList;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.jboss.weld.bootstrap.spi.BeanDiscoveryMode;
import org.jboss.weld.bootstrap.spi.BeansXml;
import org.jboss.weld.bootstrap.spi.ClassAvailableActivation;
import org.jboss.weld.bootstrap.spi.Filter;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.bootstrap.spi.SystemPropertyActivation;
import org.jboss.weld.logging.XmlLogger;
import org.jboss.weld.metadata.BeansXmlImpl;
import org.jboss.weld.metadata.ClassAvailableActivationImpl;
import org.jboss.weld.metadata.FilterImpl;
import org.jboss.weld.metadata.ScanningImpl;
import org.jboss.weld.metadata.SystemPropertyActivationImpl;
import org.jboss.weld.metadata.WeldFilterImpl;
import org.jboss.weld.util.collections.ImmutableSet;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* An implementation of the beans.xml parser written using SAX
*
* This class is NOT threadsafe, and should only be called in a single thread
*
* @author Pete Muir
*/
public class BeansXmlHandler extends DefaultHandler {
private static final String VALUE_ATTRIBUTE_QUALIFIED_NAME = "value";
private static final String PATTERN_ATTRIBUTE_QUALIFIED_NAME = "pattern";
private static final String NAME_ATTRIBUTE_QUALIFIED_NAME = "name";
protected static String trim(String str) {
if (str == null) {
return null;
} else {
return str.trim();
}
}
public abstract class Container {
private final Set uris;
private final String localName;
private final Collection nestedElements;
public Container(Set uris, String localName, String... nestedElements) {
this.uris = uris;
this.localName = localName;
this.nestedElements = asList(nestedElements);
}
public String getLocalName() {
return localName;
}
public Set getUris() {
return uris;
}
/**
* Called by startElement, the nested content is not available
*/
public void processStartChildElement(String uri, String localName, String qName, Attributes attributes) {
}
/**
* Called by endElement, the nested content is not available
*/
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
}
public void handleMultiple() {
}
public Collection getNestedElements() {
return nestedElements;
}
@Override
public String toString() {
return "<" + localName + " />";
}
protected boolean isInNamespace(String namespace) {
if (namespace.length() == 0) {
return true;
}
return getUris().contains(namespace);
}
}
private abstract class SpecContainer extends Container {
public SpecContainer(String localName, String... nestedElements) {
super(JAVAEE_URIS, localName, nestedElements);
}
}
public static final String JAVAEE_LEGACY_URI = "http://java.sun.com/xml/ns/javaee";
public static final String JAVAEE_URI = "http://xmlns.jcp.org/xml/ns/javaee";
public static final Set JAVAEE_URIS = ImmutableSet.of(JAVAEE_LEGACY_URI, JAVAEE_URI);
public static final String WELD_URI = "http://jboss.org/schema/weld/beans";
public static final Set SCANNING_URI = ImmutableSet.of(WELD_URI, JAVAEE_URI, JAVAEE_LEGACY_URI);
private static final String VERSION_ATTRIBUTE_NAME = "version";
private static final String BEAN_DISCOVERY_MODE_ATTRIBUTE_NAME = "bean-discovery-mode";
private static final String ROOT_ELEMENT_NAME = "beans";
private static final String IF_CLASS_AVAILABLE = "if-class-available";
private static final String IF_CLASS_NOT_AVAILABLE = "if-class-not-available";
private static final String IF_SYSTEM_PROPERTY = "if-system-property";
private static final String CLASS = "class";
private static final String STEREOTYPE = "stereotype";
private static final String INCLUDE = "include";
private static final String EXCLUDE = "exclude";
private static final String TRIM = "trim";
// See also http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#cvc-elt
private static final String VALIDATION_ERROR_CODE_CVC_ELT_1 = "cvc-elt.1";
/*
* The containers we are parsing
*/
private final Collection containers;
/*
* Storage for parsed info
*/
private final List> interceptors;
private final List> decorators;
private final List> alternativesClasses;
private final List> alternativeStereotypes;
private final List> includes;
private final List> excludes;
protected final URL file;
private BeanDiscoveryMode discoveryMode;
private String version;
private boolean isTrimmed;
/*
* Parser State
*/
private Collection seenContainers;
private Container currentContainer;
private StringBuilder buffer;
private Locator locator;
public BeansXmlHandler(final URL file) {
this.file = file;
this.interceptors = new ArrayList>();
this.decorators = new ArrayList>();
this.alternativesClasses = new ArrayList>();
this.alternativeStereotypes = new ArrayList>();
this.includes = new ArrayList>();
this.excludes = new ArrayList>();
this.seenContainers = new ArrayList();
this.containers = new ArrayList();
this.discoveryMode = BeanDiscoveryMode.ALL; // this is the default value for a beans.xml file
this.isTrimmed = false;
containers.add(new SpecContainer("interceptors", CLASS) {
@Override
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
if (isInNamespace(uri) && CLASS.equals(localName)) {
interceptors.add(new XmlMetadata(qName, trim(nestedText), file, locator.getLineNumber()));
}
}
@Override
public void handleMultiple() {
throw XmlLogger.LOG.multipleInterceptors(file + "@" + locator.getLineNumber());
}
});
containers.add(new SpecContainer("decorators", CLASS) {
@Override
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
if (isInNamespace(uri) && CLASS.equals(localName)) {
decorators.add(new XmlMetadata(qName, trim(nestedText), file, locator.getLineNumber()));
}
}
@Override
public void handleMultiple() {
throw XmlLogger.LOG.multipleDecorators(file + "@" + locator.getLineNumber());
}
});
containers.add(new SpecContainer("alternatives", CLASS, STEREOTYPE) {
@Override
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
if (isInNamespace(uri) && CLASS.equals(localName)) {
alternativesClasses.add(new XmlMetadata(qName, trim(nestedText), file, locator.getLineNumber()));
} else if (isInNamespace(uri) && STEREOTYPE.equals(localName)) {
alternativeStereotypes.add(new XmlMetadata(qName, trim(nestedText), file, locator.getLineNumber()));
}
}
@Override
public void handleMultiple() {
throw XmlLogger.LOG.multipleAlternatives(file + "@" + locator.getLineNumber());
}
});
containers.add(new Container(SCANNING_URI, "scan") {
String name;
String pattern;
Collection> systemPropertyActivations;
Collection> classAvailableActivations;
@Override
public void processStartChildElement(String uri, String localName, String qName, Attributes attributes) {
if (isFilterElement(uri, localName)) {
name = interpolateAttributeValue(attributes, NAME_ATTRIBUTE_QUALIFIED_NAME);
pattern = interpolateAttributeValue(attributes, PATTERN_ATTRIBUTE_QUALIFIED_NAME);
systemPropertyActivations = new ArrayList>();
classAvailableActivations = new ArrayList>();
} else if (isInNamespace(uri)) {
if (IF_CLASS_AVAILABLE.equals(localName) || IF_CLASS_NOT_AVAILABLE.equals(localName)) {
String className = interpolateAttributeValue(attributes, NAME_ATTRIBUTE_QUALIFIED_NAME);
Metadata classAvailableActivation = new XmlMetadata(qName,
new ClassAvailableActivationImpl(className, IF_CLASS_NOT_AVAILABLE.equals(localName)), file, locator.getLineNumber());
classAvailableActivations.add(classAvailableActivation);
} else if (IF_SYSTEM_PROPERTY.equals(localName)) {
String systemPropertyName = interpolateAttributeValue(attributes, NAME_ATTRIBUTE_QUALIFIED_NAME);
String systemPropertyValue = interpolateAttributeValue(attributes, VALUE_ATTRIBUTE_QUALIFIED_NAME);
Metadata systemPropertyActivation = new XmlMetadata(qName,
new SystemPropertyActivationImpl(systemPropertyName, systemPropertyValue), file, locator.getLineNumber());
systemPropertyActivations.add(systemPropertyActivation);
}
}
}
private String interpolateAttributeValue(Attributes attributes, String qName) {
String value = trim(attributes.getValue(qName));
return value == null ? null : interpolate(value);
}
@Override
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
if (isFilterElement(uri, localName)) {
Filter filter = null;
if (WELD_URI.equals(uri)) {
filter = new WeldFilterImpl(name, systemPropertyActivations, classAvailableActivations, pattern);
} else {
filter = new FilterImpl(name, systemPropertyActivations, classAvailableActivations);
}
Metadata filterMetadata = new XmlMetadata(qName, filter, file, locator.getLineNumber());
if (INCLUDE.equals(localName)) {
includes.add(filterMetadata);
} else if (EXCLUDE.equals(localName)) {
excludes.add(filterMetadata);
}
// reset
name = null;
pattern = null;
systemPropertyActivations = null;
classAvailableActivations = null;
}
}
private boolean isFilterElement(String uri, String localName) {
return isInNamespace(uri) && (INCLUDE.equals(localName) || EXCLUDE.equals(localName));
}
@Override
public void handleMultiple() {
throw XmlLogger.LOG.multipleScanning(file + "@" + locator.getLineNumber());
}
});
containers.add(new SpecContainer(TRIM) {
@Override
public void processEndChildElement(String uri, String localName, String qName, String nestedText) {
if (localName.equals(TRIM)) {
isTrimmed = true;
}
}
});
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals(ROOT_ELEMENT_NAME) && ("".equals(uri) || JAVAEE_URIS.contains(uri))) {
processRootElement(attributes);
return;
}
if (currentContainer == null) {
Container container = getContainer(uri, localName);
if (container != null) {
if (seenContainers.contains(container)) {
container.handleMultiple();
}
currentContainer = container;
}
} else {
currentContainer.processStartChildElement(uri, localName, qName, attributes);
// The current container is interested in the content of this element
if (currentContainer.getNestedElements().contains(localName)) {
buffer = new StringBuilder();
}
}
}
private void processRootElement(Attributes attributes) {
String discoveryMode = attributes.getValue(BEAN_DISCOVERY_MODE_ATTRIBUTE_NAME);
if (discoveryMode != null) {
this.discoveryMode = BeanDiscoveryMode.valueOf(discoveryMode.toUpperCase());
}
String version = attributes.getValue(VERSION_ATTRIBUTE_NAME);
if (version != null) {
this.version = version;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (currentContainer != null) {
currentContainer.processEndChildElement(uri, localName, qName, buffer != null ? buffer.toString() : null);
// The current container was interested in this element
if (currentContainer.getNestedElements().contains(localName)) {
buffer = null;
}
Container container = getContainer(uri, localName);
if (container != null) {
// We are exiting the container, record it so we know it's already been declared (for error reporting)
seenContainers.add(container);
// And stop work until we find another container of interest
currentContainer = null;
}
}
}
private Container getContainer(String uri, String localName) {
return getContainer(uri, localName, containers);
}
private static Container getContainer(String uri, String localName, Collection containers) {
for (Container container : containers) {
if (uri.length() == 0) {
if (container.getLocalName().equals(localName)) {
return container;
}
} else {
if (container.getLocalName().equals(localName) && container.getUris().contains(uri)) {
return container;
}
}
}
return null;
}
public BeansXml createBeansXml() {
return new BeansXmlImpl(alternativesClasses, alternativeStereotypes, decorators, interceptors, new ScanningImpl(includes, excludes), file,
discoveryMode, version, isTrimmed);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (buffer != null) {
buffer.append(ch, start, length);
}
}
@Override
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
@Override
public void warning(SAXParseException e) throws SAXException {
XmlLogger.LOG.xsdValidationWarning(file, e.getLineNumber(), e.getMessage());
}
@Override
public void error(SAXParseException e) throws SAXException {
if (e.getMessage().startsWith(VALIDATION_ERROR_CODE_CVC_ELT_1) && e.getMessage().contains(ROOT_ELEMENT_NAME)) {
// Ignore the errors we get when there is no schema defined
return;
}
XmlLogger.LOG.xsdValidationError(file, e.getLineNumber(), e.getMessage());
}
protected String interpolate(String string) {
return string; // noop by default, integrators may override
}
}