All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.weld.xml.BeansXmlHandler Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
package org.jboss.weld.xml;

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.exceptions.DefinitionException;
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.slf4j.cal10n.LocLogger;
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;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static java.util.Arrays.asList;
import static org.jboss.weld.logging.Category.BOOTSTRAP;
import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_ALTERNATIVES;
import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_DECORATORS;
import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_INTERCEPTORS;
import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_SCANNING;
import static org.jboss.weld.logging.messages.XmlMessage.XSD_VALIDATION_ERROR;
import static org.jboss.weld.logging.messages.XmlMessage.XSD_VALIDATION_WARNING;

/**
 * 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 { static final LocLogger log = loggerFactory().getLogger(BOOTSTRAP); public abstract static class Container { private final String uri; private final String localName; private final Collection nestedElements; public Container(String uri, String localName, String... nestedElements) { this.uri = uri; this.localName = localName; this.nestedElements = asList(nestedElements); } public String getLocalName() { return localName; } public String getUri() { return uri; } /** * 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 uri) { return uri.length() == 0 || uri.equals(getUri()); } protected static String trim(String str) { if (str == null) { return null; } else { return str.trim(); } } } public static final String WELD_URI = "http://jboss.org/schema/weld/beans"; public static final String JAVAEE_URI = "http://java.sun.com/xml/ns/javaee"; /* * The containers we are parsing */ private final Collection containers; /* * Storage for parsed info */ private final List> interceptors; private final List> decorators; private final List> alternativeClasses; private final List> alternativeStereotypes; private final List> includes; private final List> excludes; private final URL file; /* * 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.alternativeClasses = new ArrayList>(); this.alternativeStereotypes = new ArrayList>(); this.includes = new ArrayList>(); this.excludes = new ArrayList>(); this.seenContainers = new ArrayList(); this.containers = new ArrayList(); containers.add(new Container(JAVAEE_URI, "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 new DefinitionException(MULTIPLE_INTERCEPTORS, file + "@" + locator.getLineNumber()); } }); containers.add(new Container(JAVAEE_URI, "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 new DefinitionException(MULTIPLE_DECORATORS, file + "@" + locator.getLineNumber()); } }); containers.add(new Container(JAVAEE_URI, "alternatives", "class", "stereotype") { @Override public void processEndChildElement(String uri, String localName, String qName, String nestedText) { if (isInNamespace(uri) && "class".equals(localName)) { alternativeClasses.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 new DefinitionException(MULTIPLE_ALTERNATIVES, file + "@" + locator.getLineNumber()); } }); containers.add(new Container(WELD_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 = trim(attributes.getValue("name")); pattern = trim(attributes.getValue("pattern")); systemPropertyActivations = new ArrayList>(); classAvailableActivations = new ArrayList>(); } else if (isInNamespace(uri) && "if-system-property".equals(localName)) { String systemPropertyName = trim(attributes.getValue("name")); String systemPropertyValue = trim(attributes.getValue("value")); Metadata systemPropertyActivation = new XmlMetadata(qName, new SystemPropertyActivationImpl(systemPropertyName, systemPropertyValue), file, locator.getLineNumber()); systemPropertyActivations.add(systemPropertyActivation); } else if (isInNamespace(uri) && "if-class-available".equals(localName)) { String className = trim(attributes.getValue("name")); Metadata classAvailableActivation = new XmlMetadata(qName, new ClassAvailableActivationImpl(className), file, locator.getLineNumber()); classAvailableActivations.add(classAvailableActivation); } } @Override public void processEndChildElement(String uri, String localName, String qName, String nestedText) { if (isFilterElement(uri, localName)) { Metadata filter = new XmlMetadata(qName, new FilterImpl(pattern, name, systemPropertyActivations, classAvailableActivations), file, locator.getLineNumber()); if ("include".equals(localName)) { includes.add(filter); } else if ("exclude".equals(localName)) { excludes.add(filter); } // 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 new DefinitionException(MULTIPLE_SCANNING, file + "@" + locator.getLineNumber()); } }); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 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(); } } } @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.getUri().equals(uri)) { return container; } } } return null; } public BeansXml createBeansXml() { return new BeansXmlImpl(alternativeClasses, alternativeStereotypes, decorators, interceptors, new ScanningImpl(includes, excludes)); } @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 { log.warn(XSD_VALIDATION_WARNING, file, e.getLineNumber(), e.getMessage()); } @Override public void error(SAXParseException e) throws SAXException { if (e.getMessage().equals("cvc-elt.1: Cannot find the declaration of element 'beans'.")) { // Ignore the errors we get when there is no schema defined return; } log.warn(XSD_VALIDATION_ERROR, file, e.getLineNumber(), e.getMessage()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy