/*
* JBoss, Home of Professional Open Source.
* Copyright 2010, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.pojo.descriptor;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import org.jboss.as.pojo.BeanState;
import org.jboss.as.pojo.ParseResult;
import org.jboss.as.pojo.logging.PojoLogger;
import org.jboss.staxmapper.XMLElementReader;
import org.jboss.staxmapper.XMLExtendedStreamReader;
import static org.jboss.as.controller.parsing.ParseUtils.missingRequired;
import static org.jboss.as.controller.parsing.ParseUtils.unexpectedAttribute;
import static org.jboss.as.controller.parsing.ParseUtils.unexpectedElement;
/**
* Parse Microcontainer jboss-beans.xml.
*
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
*/
public class KernelDeploymentXmlDescriptorParser implements XMLElementReader<ParseResult<KernelDeploymentXmlDescriptor>>, XMLStreamConstants {
public static final String NAMESPACE = "urn:jboss:pojo:7.0";
private enum Element {
BEAN("bean"),
BEAN_FACTORY("bean-factory"),
CLASSLOADER("classloader"),
CONSTRUCTOR("constructor"),
FACTORY("factory"),
PROPERTY("property"),
VALUE("value"),
INJECT("inject"),
VALUE_FACTORY("value-factory"),
PARAMETER("parameter"),
DEPENDS("depends"),
ALIAS("alias"),
ANNOTATION("annotation"),
CREATE("create"),
START("start"),
STOP("stop"),
DESTROY("destroy"),
INSTALL("install"),
UNINSTALL("uninstall"),
INCALLBACK("incallback"),
UNCALLBACK("uncallback"),
LIST("list"),
SET("set"),
MAP("map"),
ENTRY("entry"),
KEY("key"),
UNKNOWN(null);
private final String localPart;
private static final Map<String, Element> QNAME_MAP = new HashMap<String, Element>();
static {
for (Element element : Element.values()) {
QNAME_MAP.put(element.localPart, element);
}
}
private Element(final String localPart) {
this.localPart = localPart;
}
static Element of(String localPart) {
final Element element = QNAME_MAP.get(localPart);
return element == null ? UNKNOWN : element;
}
}
private enum Attribute {
MODE("mode"),
NAME("name"),
TYPE("type"),
VALUE("value"),
TRIM("trim"),
REPLACE("replace"),
BEAN("bean"),
SERVICE("service"),
PROPERTY("property"),
CLASS("class"),
ELEMENT("elementClass"),
KEY_ELEMENT("keyClass"),
VALUE_ELEMENT("valueClass"),
METHOD("method"),
IGNORED("ignored"),
SIGNATURE("signature"),
FACTORY_CLASS("factory-class"),
FACTORY_METHOD("factory-method"),
FACTORY_CLASS_LEGACY("factoryClass"),
FACTORY_METHOD_LEGACY("factoryMethod"),
STATE("state"),
TARGET_STATE("targetState"),
UNKNOWN(null);
private final String localPart;
private static final Map<String, Attribute> QNAME_MAP = new HashMap<String, Attribute>();
static {
for (Attribute attribute : Attribute.values()) {
QNAME_MAP.put(attribute.localPart, attribute);
}
}
private Attribute(final String localPart) {
this.localPart = localPart;
}
static Attribute of(String localPart) {
final Attribute attribute = QNAME_MAP.get(localPart);
return attribute == null ? UNKNOWN : attribute;
}
}
@Override
public void readElement(XMLExtendedStreamReader reader, ParseResult<KernelDeploymentXmlDescriptor> value) throws XMLStreamException {
final KernelDeploymentXmlDescriptor kernelDeploymentXmlDescriptor = new KernelDeploymentXmlDescriptor();
final List<BeanMetaDataConfig> beansConfigs = new ArrayList<BeanMetaDataConfig>();
kernelDeploymentXmlDescriptor.setBeans(beansConfigs);
value.setResult(kernelDeploymentXmlDescriptor);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final String attributeName = reader.getAttributeLocalName(i);
final Attribute attribute = Attribute.of(attributeName);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case MODE:
kernelDeploymentXmlDescriptor.setMode(ModeConfig.of(attributeValue));
break;
}
}
while (reader.hasNext()) {
switch (reader.nextTag()) {
case COMMENT:
break;
case END_ELEMENT:
return;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case BEAN:
beansConfigs.add(parseBean(reader));
break;
case BEAN_FACTORY:
BeanMetaDataConfig bean = parseBean(reader);
beansConfigs.add(toBeanFactory(bean));
kernelDeploymentXmlDescriptor.incrementBeanFactoryCount();
break;
case UNKNOWN:
throw unexpectedElement(reader);
}
break;
}
}
}
private BeanMetaDataConfig toBeanFactory(final BeanMetaDataConfig bean) {
return new BeanFactoryMetaDataConfig(bean);
}
private BeanMetaDataConfig parseBean(final XMLExtendedStreamReader reader) throws XMLStreamException {
BeanMetaDataConfig beanConfig = new BeanMetaDataConfig();
final int count = reader.getAttributeCount();
final Set<Attribute> required = EnumSet.of(Attribute.NAME);
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case NAME:
beanConfig.setName(attributeValue);
break;
case CLASS:
beanConfig.setBeanClass(attributeValue);
break;
case MODE:
beanConfig.setMode(ModeConfig.of(attributeValue));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
while (reader.hasNext()) {
switch (reader.nextTag()) {
case COMMENT:
break;
case END_ELEMENT:
return beanConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case ALIAS:
Set<String> aliases = beanConfig.getAliases();
if (aliases == null) {
aliases = new HashSet<String>();
beanConfig.setAliases(aliases);
}
aliases.add(parseAlias(reader));
break;
case CLASSLOADER:
beanConfig.setModule(parseModuleConfig(reader));
break;
case CONSTRUCTOR:
beanConfig.setConstructor(parseConstructor(reader));
break;
case PROPERTY:
Set<PropertyConfig> properties = beanConfig.getProperties();
if (properties == null) {
properties = new HashSet<PropertyConfig>();
beanConfig.setProperties(properties);
}
properties.add(parseProperty(reader));
break;
case INSTALL:
List<InstallConfig> installs = beanConfig.getInstalls();
if (installs == null) {
installs = new ArrayList<InstallConfig>();
beanConfig.setInstalls(installs);
}
installs.add(parseInstall(reader));
break;
case UNINSTALL:
List<InstallConfig> uninstalls = beanConfig.getUninstalls();
if (uninstalls == null) {
uninstalls = new ArrayList<InstallConfig>();
beanConfig.setUninstalls(uninstalls);
}
uninstalls.add(parseInstall(reader));
break;
case INCALLBACK:
List<CallbackConfig> incallbacks = beanConfig.getIncallbacks();
if (incallbacks == null) {
incallbacks = new ArrayList<CallbackConfig>();
beanConfig.setIncallbacks(incallbacks);
}
incallbacks.add(parseCallback(reader));
break;
case UNCALLBACK:
List<CallbackConfig> uncallbacks = beanConfig.getUncallbacks();
if (uncallbacks == null) {
uncallbacks = new ArrayList<CallbackConfig>();
beanConfig.setUncallbacks(uncallbacks);
}
uncallbacks.add(parseCallback(reader));
break;
case DEPENDS:
Set<DependsConfig> depends = beanConfig.getDepends();
if (depends == null) {
depends = new HashSet<DependsConfig>();
beanConfig.setDepends(depends);
}
depends.add(parseDepends(reader));
break;
case CREATE:
beanConfig.setCreate(parseLifecycle(reader, "create"));
break;
case START:
beanConfig.setStart(parseLifecycle(reader, "start"));
break;
case STOP:
beanConfig.setStop(parseLifecycle(reader, "stop"));
break;
case DESTROY:
beanConfig.setDestroy(parseLifecycle(reader, "destroy"));
break;
case UNKNOWN:
throw unexpectedElement(reader);
}
break;
}
}
throw unexpectedElement(reader);
}
private String parseAlias(final XMLExtendedStreamReader reader) throws XMLStreamException {
final String alias = parseTextElement(reader);
if (alias == null || alias.trim().length() == 0)
throw PojoLogger.ROOT_LOGGER.nullOrEmptyAlias();
return alias;
}
private ConstructorConfig parseConstructor(final XMLExtendedStreamReader reader) throws XMLStreamException {
final ConstructorConfig ctorConfig = new ConstructorConfig();
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case FACTORY_CLASS:
case FACTORY_CLASS_LEGACY:
ctorConfig.setFactoryClass(attributeValue);
break;
case FACTORY_METHOD:
case FACTORY_METHOD_LEGACY:
ctorConfig.setFactoryMethod(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
List<ValueConfig> parameters = new ArrayList<ValueConfig>();
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
ctorConfig.setParameters(parameters.toArray(new ValueConfig[parameters.size()]));
return ctorConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case FACTORY:
ctorConfig.setFactory(parseFactory(reader));
break;
case PARAMETER:
ValueConfig p = parseParameter(reader);
p.setIndex(parameters.size());
parameters.add(p);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ModuleConfig parseModuleConfig(final XMLExtendedStreamReader reader) throws XMLStreamException {
final ModuleConfig moduleConfig = new ModuleConfig();
final int count = reader.getAttributeCount();
final Set<Attribute> required = EnumSet.of(Attribute.NAME);
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case NAME:
moduleConfig.setModuleName(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
return moduleConfig;
}
private PropertyConfig parseProperty(final XMLExtendedStreamReader reader) throws XMLStreamException {
final PropertyConfig property = new PropertyConfig();
final Set<Attribute> required = EnumSet.of(Attribute.NAME);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case NAME:
property.setPropertyName(attributeValue);
break;
case CLASS:
property.setType(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return property;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case VALUE:
property.setValue(parseValue(reader));
break;
case INJECT:
property.setValue(parseInject(reader));
break;
case VALUE_FACTORY:
property.setValue(parseValueFactory(reader));
break;
case LIST:
property.setValue(parseList(reader));
break;
case SET:
property.setValue(parseSet(reader));
break;
case MAP:
property.setValue(parseMap(reader));
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private InstallConfig parseInstall(final XMLExtendedStreamReader reader) throws XMLStreamException {
final InstallConfig installConfig = new InstallConfig();
final Set<Attribute> required = EnumSet.of(Attribute.METHOD);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case STATE:
installConfig.setWhenRequired(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case TARGET_STATE:
installConfig.setDependencyState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case BEAN:
installConfig.setDependency(attributeValue);
break;
case METHOD:
installConfig.setMethodName(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
List<ValueConfig> parameters = new ArrayList<ValueConfig>();
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
installConfig.setParameters(parameters.toArray(new ValueConfig[parameters.size()]));
return installConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case PARAMETER:
ValueConfig p = parseParameter(reader);
p.setIndex(parameters.size());
parameters.add(p);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private CallbackConfig parseCallback(final XMLExtendedStreamReader reader) throws XMLStreamException {
final CallbackConfig callbackConfig = new CallbackConfig();
final Set<Attribute> required = EnumSet.of(Attribute.METHOD);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case STATE:
callbackConfig.setWhenRequired(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case TARGET_STATE:
callbackConfig.setState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case METHOD:
callbackConfig.setMethodName(attributeValue);
break;
case SIGNATURE:
callbackConfig.setSignature(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return callbackConfig;
}
}
throw unexpectedElement(reader);
}
private DependsConfig parseDepends(final XMLExtendedStreamReader reader) throws XMLStreamException {
final DependsConfig dependsConfig = new DependsConfig();
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case STATE:
dependsConfig.setWhenRequired(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case TARGET_STATE:
dependsConfig.setDependencyState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case SERVICE:
dependsConfig.setService(Boolean.parseBoolean(attributeValue));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
String dependency = parseTextElement(reader);
if (dependency == null || dependency.trim().length() == 0)
throw PojoLogger.ROOT_LOGGER.nullOrEmptyDependency();
dependsConfig.setDependency(dependency);
return dependsConfig;
}
private LifecycleConfig parseLifecycle(final XMLExtendedStreamReader reader, String defaultMethodName) throws XMLStreamException {
final LifecycleConfig lifecycleConfig = new LifecycleConfig();
lifecycleConfig.setMethodName(defaultMethodName); // set default
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case METHOD:
lifecycleConfig.setMethodName(attributeValue);
break;
case IGNORED:
lifecycleConfig.setIgnored(Boolean.parseBoolean(attributeValue));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
List<ValueConfig> parameters = new ArrayList<ValueConfig>();
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
lifecycleConfig.setParameters(parameters.toArray(new ValueConfig[parameters.size()]));
return lifecycleConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case PARAMETER:
ValueConfig p = parseParameter(reader);
p.setIndex(parameters.size());
parameters.add(p);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ValueConfig parseParameter(final XMLExtendedStreamReader reader) throws XMLStreamException {
ValueConfig valueConfig = null;
String type = null;
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case CLASS:
type = attributeValue;
break;
default:
throw unexpectedAttribute(reader, i);
}
}
while (reader.hasNext()) {
switch (reader.next()) {
case CHARACTERS:
final StringValueConfig svc = new StringValueConfig();
svc.setValue(reader.getText());
valueConfig = svc;
break;
case END_ELEMENT:
if (valueConfig == null)
throw new XMLStreamException(PojoLogger.ROOT_LOGGER.missingValue(), reader.getLocation());
if (valueConfig.getType() == null)
valueConfig.setType(type);
return valueConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case VALUE:
valueConfig = parseValue(reader);
break;
case INJECT:
valueConfig = parseInject(reader);
break;
case VALUE_FACTORY:
valueConfig = parseValueFactory(reader);
break;
case LIST:
valueConfig = parseList(reader);
break;
case SET:
valueConfig = parseSet(reader);
break;
case MAP:
valueConfig = parseMap(reader);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private InjectedValueConfig parseInject(final XMLExtendedStreamReader reader) throws XMLStreamException {
final InjectedValueConfig injectedValueConfig = new InjectedValueConfig();
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case BEAN:
injectedValueConfig.setBean(attributeValue);
break;
case STATE:
injectedValueConfig.setState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
case SERVICE:
injectedValueConfig.setService(attributeValue);
break;
case PROPERTY:
injectedValueConfig.setProperty(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return injectedValueConfig;
}
}
throw unexpectedElement(reader);
}
private FactoryConfig parseFactory(final XMLExtendedStreamReader reader) throws XMLStreamException {
final FactoryConfig factoryConfig = new FactoryConfig();
final Set<Attribute> required = EnumSet.of(Attribute.BEAN);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case BEAN:
factoryConfig.setBean(attributeValue);
break;
case STATE:
factoryConfig.setState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return factoryConfig;
}
}
throw unexpectedElement(reader);
}
private ValueConfig parseList(final XMLExtendedStreamReader reader) throws XMLStreamException {
return parseCollection(reader, new ListConfig());
}
private ValueConfig parseSet(final XMLExtendedStreamReader reader) throws XMLStreamException {
return parseCollection(reader, new SetConfig());
}
private ValueConfig parseCollection(final XMLExtendedStreamReader reader, CollectionConfig config) throws XMLStreamException {
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case CLASS:
config.setType(attributeValue);
break;
case ELEMENT:
config.setElementType(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return config;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case VALUE:
config.addValue(parseValue(reader));
break;
case INJECT:
config.addValue(parseInject(reader));
break;
case VALUE_FACTORY:
config.addValue(parseValueFactory(reader));
break;
case LIST:
config.addValue(parseList(reader));
break;
case SET:
config.addValue(parseSet(reader));
break;
case MAP:
config.addValue(parseMap(reader));
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ValueConfig parseMap(final XMLExtendedStreamReader reader) throws XMLStreamException {
MapConfig mapConfig = new MapConfig();
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case CLASS:
mapConfig.setType(attributeValue);
break;
case KEY_ELEMENT:
mapConfig.setKeyType(attributeValue);
break;
case VALUE_ELEMENT:
mapConfig.setValueType(attributeValue);
break;
default:
throw unexpectedAttribute(reader, i);
}
}
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return mapConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case ENTRY:
ValueConfig[] entry = parseEntry(reader);
mapConfig.put(entry[0], entry[1]);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ValueConfig[] parseEntry(final XMLExtendedStreamReader reader) throws XMLStreamException {
ValueConfig[] entry = new ValueConfig[2];
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return entry;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case KEY:
entry[0] = parseValueValue(reader);
break;
case VALUE:
entry[1] = parseValueValue(reader);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ValueConfig parseValueValue(final XMLExtendedStreamReader reader) throws XMLStreamException {
ValueConfig value = null;
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
if (value == null)
throw new XMLStreamException(PojoLogger.ROOT_LOGGER.missingValue(), reader.getLocation());
return value;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case VALUE:
value = parseValue(reader);
break;
case INJECT:
value = parseInject(reader);
break;
case VALUE_FACTORY:
value = parseValueFactory(reader);
break;
case LIST:
value = parseList(reader);
break;
case SET:
value = parseSet(reader);
break;
case MAP:
value = parseMap(reader);
break;
default:
throw unexpectedElement(reader);
}
break;
case CHARACTERS:
StringValueConfig svc = new StringValueConfig();
svc.setValue(reader.getText());
value = svc;
break;
}
}
throw unexpectedElement(reader);
}
private ValueFactoryConfig parseValueFactory(final XMLExtendedStreamReader reader) throws XMLStreamException {
final ValueFactoryConfig valueFactoryConfig = new ValueFactoryConfig();
final Set<Attribute> required = EnumSet.of(Attribute.BEAN, Attribute.METHOD);
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
required.remove(attribute);
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case BEAN:
valueFactoryConfig.setBean(attributeValue);
break;
case METHOD:
valueFactoryConfig.setMethod(attributeValue);
break;
case STATE:
valueFactoryConfig.setState(BeanState.valueOf(attributeValue.toUpperCase(Locale.ENGLISH)));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
if (required.isEmpty() == false) {
throw missingRequired(reader, required);
}
List<ValueConfig> parameters = new ArrayList<ValueConfig>();
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
valueFactoryConfig.setParameters(parameters.toArray(new ValueConfig[parameters.size()]));
return valueFactoryConfig;
case START_ELEMENT:
switch (Element.of(reader.getLocalName())) {
case PARAMETER:
ValueConfig p = parseParameter(reader);
p.setIndex(parameters.size());
parameters.add(p);
break;
default:
throw unexpectedElement(reader);
}
}
}
throw unexpectedElement(reader);
}
private ValueConfig parseValue(final XMLExtendedStreamReader reader) throws XMLStreamException {
final StringValueConfig valueConfig = new StringValueConfig();
final int count = reader.getAttributeCount();
for (int i = 0; i < count; i++) {
final Attribute attribute = Attribute.of(reader.getAttributeLocalName(i));
final String attributeValue = reader.getAttributeValue(i);
switch (attribute) {
case CLASS:
valueConfig.setType(attributeValue);
break;
case REPLACE:
valueConfig.setReplaceProperties(Boolean.parseBoolean(attributeValue));
break;
case TRIM:
valueConfig.setTrim(Boolean.parseBoolean(attributeValue));
break;
default:
throw unexpectedAttribute(reader, i);
}
}
valueConfig.setValue(parseTextElement(reader));
return valueConfig;
}
private String parseTextElement(final XMLExtendedStreamReader reader) throws XMLStreamException {
String value = null;
while (reader.hasNext()) {
switch (reader.next()) {
case END_ELEMENT:
return value;
case CHARACTERS:
value = reader.getText();
break;
default:
throw unexpectedElement(reader);
}
}
throw unexpectedElement(reader);
}
}