/* * JBoss, Home of Professional Open Source. * Copyright 2010, Red Hat, Inc., 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.messaging; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; import static org.jboss.as.controller.parsing.ParseUtils.missingRequired; import static org.jboss.as.controller.parsing.ParseUtils.parsePossibleExpression; import static org.jboss.as.controller.parsing.ParseUtils.readStringAttributeElement; import static org.jboss.as.controller.parsing.ParseUtils.requireNoAttributes; import static org.jboss.as.controller.parsing.ParseUtils.requireNoContent; import static org.jboss.as.controller.parsing.ParseUtils.requireNoNamespaceAttribute; import static org.jboss.as.controller.parsing.ParseUtils.requireSingleAttribute; import static org.jboss.as.controller.parsing.ParseUtils.unexpectedAttribute; import static org.jboss.as.controller.parsing.ParseUtils.unexpectedElement; import static org.jboss.as.controller.parsing.ParseUtils.unexpectedEndElement; import static org.jboss.as.messaging.CommonAttributes.ACCEPTOR; import static org.jboss.as.messaging.CommonAttributes.CONNECTION_FACTORY; import static org.jboss.as.messaging.CommonAttributes.CONNECTOR; import static org.jboss.as.messaging.CommonAttributes.DEFAULT; import static org.jboss.as.messaging.CommonAttributes.DURABLE; import static org.jboss.as.messaging.CommonAttributes.FILTER; import static org.jboss.as.messaging.CommonAttributes.HORNETQ_SERVER; import static org.jboss.as.messaging.CommonAttributes.IN_VM_ACCEPTOR; import static org.jboss.as.messaging.CommonAttributes.IN_VM_CONNECTOR; import static org.jboss.as.messaging.CommonAttributes.JMS_QUEUE; import static org.jboss.as.messaging.CommonAttributes.JMS_TOPIC; import static org.jboss.as.messaging.CommonAttributes.POOLED_CONNECTION_FACTORY; import static org.jboss.as.messaging.CommonAttributes.REMOTE_ACCEPTOR; import static org.jboss.as.messaging.CommonAttributes.REMOTE_CONNECTOR; import static org.jboss.as.messaging.CommonAttributes.REMOTING_INTERCEPTORS; import static org.jboss.as.messaging.CommonAttributes.ROLE; import static org.jboss.as.messaging.CommonAttributes.SECURITY_SETTING; import static org.jboss.as.messaging.CommonAttributes.SELECTOR; import static org.jboss.as.messaging.CommonAttributes.SUBSYSTEM; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.logging.ControllerLogger; import org.jboss.as.controller.ListAttributeDefinition; import org.jboss.as.controller.SimpleAttributeDefinition; import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.parsing.ParseUtils; import org.jboss.as.messaging.jms.ConnectionFactoryAttributes.Common; import org.jboss.as.messaging.jms.ConnectionFactoryAttributes.Pooled; import org.jboss.as.messaging.logging.MessagingLogger; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.staxmapper.XMLElementReader; import org.jboss.staxmapper.XMLExtendedStreamReader; /** * The messaging subsystem domain parser * * @author scott.stark@jboss.org * @author Emanuel Muckenhuber * @author <a href="mailto:andy.taylor@jboss.com">Andy Taylor</a> * @author Brian Stansberry (c) 2011 Red Hat Inc. */ public class MessagingSubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>> { private static final EnumSet<Element> SIMPLE_ROOT_RESOURCE_ELEMENTS = EnumSet.noneOf(Element.class); static { for (AttributeDefinition attr : CommonAttributes.SIMPLE_ROOT_RESOURCE_ATTRIBUTES) { SIMPLE_ROOT_RESOURCE_ELEMENTS.add(Element.forName(attr.getXmlName())); } } protected MessagingSubsystemParser() { // } public void readElement(final XMLExtendedStreamReader reader, final List<ModelNode> list) throws XMLStreamException { final ModelNode address = new ModelNode(); address.add(SUBSYSTEM, MessagingExtension.SUBSYSTEM_NAME); address.protect(); final ModelNode subsystemAdd = new ModelNode(); subsystemAdd.get(OP).set(ADD); subsystemAdd.get(OP_ADDR).set(address); list.add(subsystemAdd); final Namespace schemaVer = Namespace.forUri(reader.getNamespaceURI()); switch (schemaVer) { case MESSAGING_1_0: processHornetQServer(reader, address, list, schemaVer); break; case MESSAGING_1_1: case MESSAGING_1_2: case MESSAGING_1_3: case MESSAGING_1_4: case MESSAGING_1_5: case MESSAGING_2_0: case MESSAGING_3_0: processHornetQServers(reader, address, list); break; default: throw unexpectedElement(reader); } } protected void processHornetQServers(final XMLExtendedStreamReader reader, final ModelNode subsystemAddress, final List<ModelNode> list) throws XMLStreamException { while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Namespace schemaVer = Namespace.forUri(reader.getNamespaceURI()); switch (schemaVer) { case MESSAGING_1_0: case UNKNOWN: throw ParseUtils.unexpectedElement(reader); default: { final Element element = Element.forName(reader.getLocalName()); switch (element) { case HORNETQ_SERVER: processHornetQServer(reader, subsystemAddress, list, schemaVer); break; default: throw ParseUtils.unexpectedElement(reader); } } } } } protected void processHornetQServer(final XMLExtendedStreamReader reader, final ModelNode subsystemAddress, final List<ModelNode> list, Namespace namespace) throws XMLStreamException { String hqServerName = null; String elementName = null; switch (namespace) { case MESSAGING_1_0: // We're parsing the 1.0 xsd's <subsystem> element requireNoAttributes(reader); elementName = ModelDescriptionConstants.SUBSYSTEM; break; default: { final int count = reader.getAttributeCount(); if (count > 0) { requireSingleAttribute(reader, Attribute.NAME.getLocalName()); hqServerName = reader.getAttributeValue(0).trim(); } elementName = CommonAttributes.HORNETQ_SERVER; } } if (hqServerName == null || hqServerName.length() == 0) { hqServerName = DEFAULT; } final ModelNode address = subsystemAddress.clone(); address.add(HORNETQ_SERVER, hqServerName); address.protect(); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); operation.get(OP_ADDR).set(address); list.add(operation); EnumSet<Element> seen = EnumSet.noneOf(Element.class); // Handle elements String localName = null; do { reader.nextTag(); localName = reader.getLocalName(); final Element element = Element.forName(reader.getLocalName()); if (!seen.add(element)) { throw ParseUtils.duplicateNamedElement(reader, element.getLocalName()); } switch (element) { case ACCEPTORS: processAcceptors(reader, address, list); break; case ADDRESS_SETTINGS: processAddressSettings(reader, address, list); break; case BINDINGS_DIRECTORY: parseDirectory(reader, CommonAttributes.BINDINGS_DIRECTORY, address, list); break; case BRIDGES: processBridges(reader, address, list); break; case BROADCAST_GROUPS: processBroadcastGroups(reader, address, list); break; case CLUSTER_CONNECTIONS: processClusterConnections(reader, address, list); break; case CONNECTORS: processConnectors(reader, address, list); break; case CONNECTOR_SERVICES: processConnectorServices(reader, address, list); break; case DISCOVERY_GROUPS: processDiscoveryGroups(reader, address, list); break; case DIVERTS: parseDiverts(reader, address, list); break; case FILE_DEPLOYMENT_ENABLED: // This isn't an element in the xsd as there is no filesystem support in AS unhandledElement(reader, element); break; case GROUPING_HANDLER: processGroupingHandler(reader, address, list); break; case JOURNAL_DIRECTORY: parseDirectory(reader, CommonAttributes.JOURNAL_DIRECTORY, address, list); break; case LARGE_MESSAGES_DIRECTORY: parseDirectory(reader, CommonAttributes.LARGE_MESSAGES_DIRECTORY, address, list); break; case LIVE_CONNECTOR_REF: { MessagingLogger.ROOT_LOGGER.deprecatedXMLElement(element.toString()); skipElementText(reader); break; } case PAGING_DIRECTORY: parseDirectory(reader, CommonAttributes.PAGING_DIRECTORY, address, list); break; case REMOTING_INTERCEPTORS: processRemotingInterceptors(reader, operation); break; case SECURITY_DOMAIN: handleElementText(reader, element, null, operation); break; case SECURITY_SETTINGS: { // process security settings processSecuritySettings(reader, address, list); break; } case CORE_QUEUES: { parseQueues(reader, address, list); break; } case CONNECTION_FACTORIES: { processConnectionFactories(reader, address, list); break; } case JMS_DESTINATIONS: { processJmsDestinations(reader, address, list); break; } case SCHEDULED_THREAD_POOL_MAX_SIZE: case THREAD_POOL_MAX_SIZE: { // Use the "server" variant handleElementText(reader, element, "server", operation); break; } case MESSAGE_COUNTER_ENABLED: { MessagingLogger.ROOT_LOGGER.deprecatedXMLElement(element.toString(), Element.STATISTICS_ENABLED.toString()); handleElementText(reader, element, operation); break; } case HORNETQ_SERVER: // The end of the hornetq-server element if (namespace == Namespace.MESSAGING_1_0) { throw unexpectedEndElement(reader); } break; case SUBSYSTEM: // The end of the subsystem element if (namespace != Namespace.MESSAGING_1_0) { throw unexpectedEndElement(reader); } break; case CLUSTERED: // log that the attribute is deprecated but handle it anyway MessagingLogger.ROOT_LOGGER.deprecatedXMLElement(element.toString()); default: if (SIMPLE_ROOT_RESOURCE_ELEMENTS.contains(element)) { AttributeDefinition attributeDefinition = element.getDefinition(); if (attributeDefinition instanceof SimpleAttributeDefinition) { handleElementText(reader, element, operation); } else { // These should be handled in specific case blocks above, e.g. case REMOTING_INTERCEPTORS: handleComplexConfigurationAttribute(reader, element, operation); } } else { handleUnknownConfigurationAttribute(reader, element, operation); } } } while (reader.hasNext() && localName.equals(elementName) == false); } protected void handleComplexConfigurationAttribute(XMLExtendedStreamReader reader, Element element, ModelNode operation) throws XMLStreamException { throw MessagingLogger.ROOT_LOGGER.unsupportedElement(element.getLocalName()); } protected void handleUnknownConfigurationAttribute(XMLExtendedStreamReader reader, Element element, ModelNode operation) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } private static void processConnectorServices(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case CONNECTOR_SERVICE: { processConnectorService(reader, address, updates); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } private static void processConnectorService(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); String name = reader.getAttributeValue(0); final ModelNode serviceAddress = address.clone().add(CommonAttributes.CONNECTOR_SERVICE, name); final ModelNode add = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, serviceAddress); updates.add(add); EnumSet<Element> required = EnumSet.of(Element.FACTORY_CLASS); Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); if (!seen.add(element) && element != Element.PARAM) { throw ParseUtils.duplicateNamedElement(reader, element.getLocalName()); } required.remove(element); switch (element) { case FACTORY_CLASS: { handleElementText(reader, element, add); break; } case PARAM: { String[] attrs = ParseUtils.requireAttributes(reader, Attribute.KEY.getLocalName(), Attribute.VALUE.getLocalName()); final String key = attrs[0]; final String value = attrs[1]; final ModelNode paramAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, serviceAddress.clone().add(CommonAttributes.PARAM, key)); ConnectorServiceParamDefinition.VALUE.parseAndSetParameter(value, paramAdd, reader); updates.add(paramAdd); requireNoContent(reader); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } if(!required.isEmpty()) { throw missingRequired(reader, required); } } private void processClusterConnections(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case CLUSTER_CONNECTION: { processClusterConnection(reader, address, updates); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } protected void processClusterConnection(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); String name = reader.getAttributeValue(0); ModelNode clusterConnectionAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.CLUSTER_CONNECTION, name)); EnumSet<Element> required = EnumSet.of(Element.ADDRESS, Element.CONNECTOR_REF); Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); if (!seen.add(element)) { throw ParseUtils.duplicateNamedElement(reader, element.getLocalName()); } required.remove(element); switch (element) { case FORWARD_WHEN_NO_CONSUMERS: case MAX_HOPS: handleElementText(reader, element, clusterConnectionAdd); break; case ADDRESS: { handleElementText(reader, element, ClusterConnectionDefinition.ADDRESS.getName(), clusterConnectionAdd); break; } case CONNECTOR_REF: { // Use the "simple" variant handleElementText(reader, element, "simple", clusterConnectionAdd); break; } case CONFIRMATION_WINDOW_SIZE: handleElementText(reader, element, "bridge", clusterConnectionAdd); break; case USE_DUPLICATE_DETECTION: case RETRY_INTERVAL: // Use the "cluster" variant handleElementText(reader, element, "cluster", clusterConnectionAdd); break; case STATIC_CONNECTORS: checkOtherElementIsNotAlreadyDefined(reader, seen, Element.STATIC_CONNECTORS, Element.DISCOVERY_GROUP_REF); processStaticConnectors(reader, clusterConnectionAdd, true); break; case DISCOVERY_GROUP_REF: { checkOtherElementIsNotAlreadyDefined(reader, seen, Element.DISCOVERY_GROUP_REF, Element.STATIC_CONNECTORS); final String groupRef = readStringAttributeElement(reader, ClusterConnectionDefinition.DISCOVERY_GROUP_NAME.getXmlName()); ClusterConnectionDefinition.DISCOVERY_GROUP_NAME.parseAndSetParameter(groupRef, clusterConnectionAdd, reader); break; } default: { handleUnknownClusterConnectionAttribute(reader, element, clusterConnectionAdd); } } } if(!required.isEmpty()) { throw missingRequired(reader, required); } checkClusterConnectionConstraints(reader, seen); updates.add(clusterConnectionAdd); } protected void handleUnknownClusterConnectionAttribute(XMLExtendedStreamReader reader, Element element, ModelNode clusterConnectionAdd) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } protected void checkClusterConnectionConstraints(XMLExtendedStreamReader reader, Set<Element> seen) throws XMLStreamException { } protected void checkBroadcastGroupConstraints(XMLExtendedStreamReader reader, Set<Element> seen) throws XMLStreamException { checkOnlyOneOfElements(reader, seen, Element.GROUP_ADDRESS, Element.SOCKET_BINDING); if (seen.contains(Element.GROUP_ADDRESS) && !seen.contains(Element.GROUP_PORT)) { throw missingRequired(reader, EnumSet.of(Element.GROUP_PORT)); } } private void processBridges(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case BRIDGE: { processBridge(reader, address, updates); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } protected void processBridge(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); String name = reader.getAttributeValue(0); ModelNode bridgeAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.BRIDGE, name)); EnumSet<Element> required = EnumSet.of(Element.QUEUE_NAME); Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); if (!seen.add(element)) { throw ParseUtils.duplicateNamedElement(reader, element.getLocalName()); } required.remove(element); switch (element) { case QUEUE_NAME: case HA: case TRANSFORMER_CLASS_NAME: case USER: case PASSWORD: handleElementText(reader, element, bridgeAdd); break; case CONFIRMATION_WINDOW_SIZE: handleElementText(reader, element, "bridge", bridgeAdd); break; case FILTER: { String string = readStringAttributeElement(reader, CommonAttributes.STRING); FILTER.parseAndSetParameter(string, bridgeAdd, reader); break; } case RETRY_INTERVAL_MULTIPLIER: case RETRY_INTERVAL: // Use the "default" variant handleElementText(reader, element, DEFAULT, bridgeAdd); break; case FORWARDING_ADDRESS: case RECONNECT_ATTEMPTS: case USE_DUPLICATE_DETECTION: handleElementText(reader, element, "bridge", bridgeAdd); break; case STATIC_CONNECTORS: checkOtherElementIsNotAlreadyDefined(reader, seen, Element.STATIC_CONNECTORS, Element.DISCOVERY_GROUP_REF); processStaticConnectors(reader, bridgeAdd, false); break; case DISCOVERY_GROUP_REF: { checkOtherElementIsNotAlreadyDefined(reader, seen, Element.DISCOVERY_GROUP_REF, Element.STATIC_CONNECTORS); final String groupRef = readStringAttributeElement(reader, BridgeDefinition.DISCOVERY_GROUP_NAME.getXmlName()); BridgeDefinition.DISCOVERY_GROUP_NAME.parseAndSetParameter(groupRef, bridgeAdd, reader); break; } case FAILOVER_ON_SERVER_SHUTDOWN: { MessagingLogger.ROOT_LOGGER.deprecatedXMLElement(element.toString()); skipElementText(reader); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } checkOnlyOneOfElements(reader, seen, Element.STATIC_CONNECTORS, Element.DISCOVERY_GROUP_REF); if(!required.isEmpty()) { throw missingRequired(reader, required); } updates.add(bridgeAdd); } protected void processStaticConnectors(XMLExtendedStreamReader reader, ModelNode addOperation, boolean cluster) throws XMLStreamException { if (cluster) { int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case ALLOW_DIRECT_CONNECTIONS_ONLY: { final String attrValue = reader.getAttributeValue(i); ClusterConnectionDefinition.ALLOW_DIRECT_CONNECTIONS_ONLY.parseAndSetParameter(attrValue, addOperation, reader); break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } } else { requireNoAttributes(reader); } EnumSet<Element> required = EnumSet.of(Element.CONNECTOR_REF); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); required.remove(element); switch (element) { case CONNECTOR_REF: { handleElementText(reader, element, cluster ? "cluster-connection" : "bridge", addOperation); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } if(!required.isEmpty()) { throw missingRequired(reader, required); } } private void processGroupingHandler(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); String name = reader.getAttributeValue(0); ModelNode groupingHandlerAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.GROUPING_HANDLER, name)); EnumSet<Element> required = EnumSet.of(Element.ADDRESS, Element.TYPE); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); required.remove(element); switch (element) { case TYPE: case TIMEOUT: { handleElementText(reader, element, groupingHandlerAdd); break; } case ADDRESS: { handleElementText(reader, element, GroupingHandlerDefinition.GROUPING_HANDLER_ADDRESS.getName(), groupingHandlerAdd); break; } default: { handleUnknownGroupingHandlerAttribute(reader, element, groupingHandlerAdd); } } } if(!required.isEmpty()) { throw missingRequired(reader, required); } updates.add(groupingHandlerAdd); } protected void handleUnknownGroupingHandlerAttribute(XMLExtendedStreamReader reader, Element element, ModelNode operation) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } private void processRemotingInterceptors(XMLExtendedStreamReader reader, ModelNode operation) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case CLASS_NAME: { final String value = reader.getElementText(); REMOTING_INTERCEPTORS.parseAndAddParameterElement(value, operation, reader); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } void processBroadcastGroups(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case BROADCAST_GROUP: { parseBroadcastGroup(reader, address, updates); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } protected void parseBroadcastGroup(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { String name = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String attrValue = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = attrValue; break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } if(name == null) { throw missingRequired(reader, Collections.singleton(Attribute.NAME)); } ModelNode broadcastGroupAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.BROADCAST_GROUP, name)); Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); seen.add(element); switch (element) { case LOCAL_BIND_ADDRESS: case LOCAL_BIND_PORT: case GROUP_ADDRESS: case GROUP_PORT: case SOCKET_BINDING: case BROADCAST_PERIOD: handleElementText(reader, element, broadcastGroupAdd); break; case CONNECTOR_REF: handleElementText(reader, element, "broadcast-group", broadcastGroupAdd); break; default: { handleUnknownBroadcastGroupAttribute(reader, element, broadcastGroupAdd); } } } checkBroadcastGroupConstraints(reader, seen); updates.add(broadcastGroupAdd); } protected void handleUnknownBroadcastGroupAttribute(XMLExtendedStreamReader reader, Element element, ModelNode operation) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } void processDiscoveryGroups(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case DISCOVERY_GROUP: { parseDiscoveryGroup(reader, address, updates); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } protected void parseDiscoveryGroup(XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { String name = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String attrValue = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = attrValue; break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } if(name == null) { throw missingRequired(reader, Collections.singleton(Attribute.NAME)); } ModelNode discoveryGroup = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.DISCOVERY_GROUP, name)); Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); seen.add(element); switch (element) { case LOCAL_BIND_ADDRESS: case GROUP_ADDRESS: case GROUP_PORT: case REFRESH_TIMEOUT: case SOCKET_BINDING: case INITIAL_WAIT_TIMEOUT: handleElementText(reader, element, discoveryGroup); break; default: { handleUnknownDiscoveryGroupAttribute(reader, element, discoveryGroup); } } } checkDiscoveryGroupConstraints(reader, seen); updates.add(discoveryGroup); } protected void handleUnknownDiscoveryGroupAttribute(XMLExtendedStreamReader reader, Element element, ModelNode operation) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } protected void checkDiscoveryGroupConstraints(XMLExtendedStreamReader reader, Set<Element> seen) throws XMLStreamException { checkOnlyOneOfElements(reader, seen, Element.GROUP_ADDRESS, Element.SOCKET_BINDING); if (seen.contains(Element.GROUP_ADDRESS) && !seen.contains(Element.GROUP_PORT)) { throw missingRequired(reader, EnumSet.of(Element.GROUP_PORT)); } } void processConnectionFactories(final XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch(element) { case CONNECTION_FACTORY: processConnectionFactory(reader, address, updates); break; case POOLED_CONNECTION_FACTORY: processPooledConnectionFactory(reader, address, updates); break; default: throw ParseUtils.unexpectedElement(reader); } } } static void processJmsDestinations(final XMLExtendedStreamReader reader, final ModelNode address, List<ModelNode> updates) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch(element) { case JMS_QUEUE: processJMSQueue(reader, address, updates); break; case JMS_TOPIC: processJMSTopic(reader, address, updates); break; default: throw ParseUtils.unexpectedElement(reader); } } } void processAcceptors(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> updates) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { String name = null; String socketBinding = null; String serverId = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String attrValue = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = attrValue; break; } case SOCKET_BINDING: { socketBinding = attrValue; break; } case SERVER_ID: { serverId = attrValue; break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } if(name == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME)); } final ModelNode acceptorAddress = address.clone(); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); boolean generic = false; final Element element = Element.forName(reader.getLocalName()); switch (element) { case ACCEPTOR: { operation.get(OP_ADDR).set(acceptorAddress.add(ACCEPTOR, name)); if(socketBinding != null) { operation.get(RemoteTransportDefinition.SOCKET_BINDING.getName()).set(socketBinding); } generic = true; break; } case NETTY_ACCEPTOR: { operation.get(OP_ADDR).set(acceptorAddress.add(REMOTE_ACCEPTOR, name)); if(socketBinding == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.SOCKET_BINDING)); } operation.get(RemoteTransportDefinition.SOCKET_BINDING.getName()).set(socketBinding); break; } case IN_VM_ACCEPTOR: { operation.get(OP_ADDR).set(acceptorAddress.add(IN_VM_ACCEPTOR, name)); if (serverId != null) { InVMTransportDefinition.SERVER_ID.parseAndSetParameter(serverId, operation, reader); } break; } default: { throw ParseUtils.unexpectedElement(reader); } } updates.add(operation); parseTransportConfiguration(reader, operation, generic, updates); } } static void parseQueues(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> list) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { String name = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String attrValue = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = attrValue; break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } final Element element = Element.forName(reader.getLocalName()); switch (element) { case QUEUE: { if(name == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.NAME.getLocalName())); } final ModelNode op = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.QUEUE, name)); parseQueue(reader, op); if(! op.hasDefined(QueueDefinition.ADDRESS.getName())) { throw ParseUtils.missingRequired(reader, Collections.singleton(Element.ADDRESS.getLocalName())); } list.add(op); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } static void parseQueue(final XMLExtendedStreamReader reader, final ModelNode queue) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case ADDRESS: { handleElementText(reader, element, QueueDefinition.ADDRESS.getName(), queue); break; } case FILTER: { String string = readStringAttributeElement(reader, CommonAttributes.STRING); FILTER.parseAndSetParameter(string, queue, reader); break; } case DURABLE: { handleElementText(reader, element, queue); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } private ModelNode processSecuritySettings(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> operations) throws XMLStreamException { final ModelNode security = new ModelNode(); String localName = null; do { reader.nextTag(); localName = reader.getLocalName(); final org.jboss.as.messaging.Element element = org.jboss.as.messaging.Element.forName(reader.getLocalName()); switch (element) { case SECURITY_SETTING: final String match = reader.getAttributeValue(0); final ModelNode addr = address.clone(); addr.add(SECURITY_SETTING, match); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); operation.get(OP_ADDR).set(addr); operations.add(operation); parseSecurityRoles(reader, addr, operations); break; } } while (reader.hasNext() && localName.equals(Element.SECURITY_SETTING.getLocalName())); return security; } private void parseSecurityRoles(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> operations) throws XMLStreamException { final Map<String, Set<AttributeDefinition>> permsByRole = new HashMap<String, Set<AttributeDefinition>>(); String localName = null; do { reader.nextTag(); localName = reader.getLocalName(); final Element element = Element.forName(localName); if (element != Element.PERMISSION_ELEMENT_NAME) { break; } final Set<Attribute> required = EnumSet.of(Attribute.ROLES_ATTR_NAME, Attribute.TYPE_ATTR_NAME); List<String> roles = null; AttributeDefinition perm = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); required.remove(attribute); switch (attribute) { case ROLES_ATTR_NAME: roles = parseRolesAttribute(reader, i); break; case TYPE_ATTR_NAME: perm = SecurityRoleDefinition.ROLE_ATTRIBUTES_BY_XML_NAME.get(reader.getAttributeValue(i)); if (perm == null) { throw ControllerLogger.ROOT_LOGGER.invalidAttributeValue(reader.getAttributeValue(i), reader.getAttributeName(i), SecurityRoleDefinition.ROLE_ATTRIBUTES_BY_XML_NAME.keySet(), reader.getLocation()); } break; default: throw ParseUtils.unexpectedAttribute(reader, i); } } if (!required.isEmpty()) { throw missingRequired(reader, required); } for (String role : roles) { role = role.trim(); Set<AttributeDefinition> perms = permsByRole.get(role); if (perms == null) { perms = new HashSet<AttributeDefinition>(); permsByRole.put(role, perms); } perms.add(perm); } // Scan to element end reader.discardRemainder(); } while (reader.hasNext()); for (Map.Entry<String, Set<AttributeDefinition>> entry : permsByRole.entrySet()) { final String role = entry.getKey(); final Set<AttributeDefinition> perms = entry.getValue(); final ModelNode addr = address.clone(); addr.add(ROLE, role); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); operation.get(OP_ADDR).set(addr); for (AttributeDefinition perm : SecurityRoleDefinition.ATTRIBUTES) { operation.get(perm.getName()).set(perms.contains(perm)); } operations.add(operation); } } protected List<String> parseRolesAttribute(final XMLExtendedStreamReader reader, int index) throws XMLStreamException { return reader.getListAttributeValue(index); } void processConnectors(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> updates) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { String name = null; String socketBinding = null; String serverId = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String attrValue = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAME: { name = attrValue; break; } case SOCKET_BINDING: { socketBinding = attrValue; break; } case SERVER_ID: { serverId = attrValue; break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } if(name == null) { throw missingRequired(reader, Collections.singleton(Attribute.NAME)); } final ModelNode connectorAddress = address.clone(); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); boolean generic = false; final Element element = Element.forName(reader.getLocalName()); switch (element) { case CONNECTOR: { operation.get(OP_ADDR).set(connectorAddress.add(CONNECTOR, name)); if(socketBinding != null) { operation.get(RemoteTransportDefinition.SOCKET_BINDING.getName()).set(socketBinding); } generic = true; break; } case NETTY_CONNECTOR: { operation.get(OP_ADDR).set(connectorAddress.add(REMOTE_CONNECTOR, name)); if(socketBinding == null) { throw missingRequired(reader, Collections.singleton(Attribute.SOCKET_BINDING)); } operation.get(RemoteTransportDefinition.SOCKET_BINDING.getName()).set(socketBinding); break; } case IN_VM_CONNECTOR: { operation.get(OP_ADDR).set(connectorAddress.add(IN_VM_CONNECTOR, name)); if (serverId != null) { InVMTransportDefinition.SERVER_ID.parseAndSetParameter(serverId, operation, reader); } break; } default: { throw ParseUtils.unexpectedElement(reader); } } updates.add(operation); parseTransportConfiguration(reader, operation, generic, updates); } } protected void processAddressSettings(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> operations) throws XMLStreamException { String localName = null; do { reader.nextTag(); localName = reader.getLocalName(); final Element element = Element.forName(localName); switch (element) { case ADDRESS_SETTING: // Add address settings final String match = reader.getAttributeValue(0); final ModelNode operation = parseAddressSettings(reader); operation.get(OP).set(ADD); operation.get(OP_ADDR).set(address); operation.get(OP_ADDR).add(CommonAttributes.ADDRESS_SETTING, match); operations.add(operation); break; } } while (reader.hasNext() && localName.equals(Element.ADDRESS_SETTING.getLocalName())); } protected ModelNode parseAddressSettings(final XMLExtendedStreamReader reader) throws XMLStreamException { final ModelNode addressSettingsSpec = new ModelNode(); String localName; do { reader.nextTag(); localName = reader.getLocalName(); final Element element = Element.forName(localName); switch (element) { case DEAD_LETTER_ADDRESS: case EXPIRY_ADDRESS: case REDELIVERY_DELAY: case MAX_SIZE_BYTES: case PAGE_MAX_CACHE_SIZE: case PAGE_SIZE_BYTES: case MESSAGE_COUNTER_HISTORY_DAY_LIMIT: case ADDRESS_FULL_MESSAGE_POLICY: case LVQ: case MAX_DELIVERY_ATTEMPTS: case REDISTRIBUTION_DELAY: case SEND_TO_DLA_ON_NO_ROUTE: { handleElementText(reader, element, addressSettingsSpec); break; } default: { handleUnknownAddressSetting(reader, element, addressSettingsSpec); break; } } } while (!reader.getLocalName().equals(Element.ADDRESS_SETTING.getLocalName()) && reader.getEventType() == XMLExtendedStreamReader.END_ELEMENT); return addressSettingsSpec; } protected void handleUnknownAddressSetting(XMLExtendedStreamReader reader, Element element, ModelNode addressSettingsAdd) throws XMLStreamException { // do nothing } void parseTransportConfiguration(final XMLExtendedStreamReader reader, final ModelNode operation, final boolean generic, List<ModelNode> updates) throws XMLStreamException { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { Element element = Element.forName(reader.getLocalName()); switch(element) { case FACTORY_CLASS: { if(! generic) { throw ParseUtils.unexpectedElement(reader); } handleElementText(reader, element, operation); break; } case PARAM: { int count = reader.getAttributeCount(); String key = null; String value = null; for (int n = 0; n < count; n++) { String attrName = reader.getAttributeLocalName(n); Attribute attribute = Attribute.forName(attrName); switch (attribute) { case KEY: key = reader.getAttributeValue(n); break; case VALUE: value = reader.getAttributeValue(n); break; default: throw unexpectedAttribute(reader, n); } } ModelNode addParam = new ModelNode(); addParam.get(OP).set(ADD); ModelNode transportAddress = operation.get(OP_ADDR).clone(); addParam.get(OP_ADDR).set(transportAddress.add(CommonAttributes.PARAM, key)); TransportParamDefinition.VALUE.parseAndSetParameter(value, addParam, reader); updates.add(addParam); ParseUtils.requireNoContent(reader); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } static void parseDirectory(final XMLExtendedStreamReader reader, final String name, final ModelNode address, final List<ModelNode> updates) throws XMLStreamException { ModelNode path = null; String relativeTo = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); final String value = reader.getAttributeValue(i); switch (attribute) { case RELATIVE_TO: relativeTo = value; break; case PATH: path = PathDefinition.PATHS.get(name).parse(value, reader); break; default: throw unexpectedAttribute(reader, i); } } if(path == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.PATH)); } requireNoContent(reader); final ModelNode operation = new ModelNode(); operation.get(OP).set(ADD); operation.get(OP_ADDR).set(address); operation.get(OP_ADDR).add(ModelDescriptionConstants.PATH, name); operation.get(ModelDescriptionConstants.PATH).set(path); if(relativeTo != null) operation.get(ModelDescriptionConstants.RELATIVE_TO).set(relativeTo); updates.add(operation); } private static void parseDiverts(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> list) throws XMLStreamException { requireNoAttributes(reader); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case DIVERT: { parseDivert(reader, address, list); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } } private static void parseDivert(final XMLExtendedStreamReader reader, final ModelNode address, final List<ModelNode> list) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); String name = reader.getAttributeValue(0); ModelNode divertAdd = org.jboss.as.controller.operations.common.Util.getEmptyOperation(ADD, address.clone().add(CommonAttributes.DIVERT, name)); EnumSet<Element> required = EnumSet.of(Element.ADDRESS, Element.FORWARDING_ADDRESS); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); required.remove(element); switch (element) { case ROUTING_NAME: { handleElementText(reader, element, divertAdd); break; } case ADDRESS: { handleElementText(reader, element, DivertDefinition.ADDRESS.getName(), divertAdd); break; } case FORWARDING_ADDRESS: { handleElementText(reader, element, "divert", divertAdd); break; } case FILTER: { String string = readStringAttributeElement(reader, CommonAttributes.STRING); FILTER.parseAndSetParameter(string, divertAdd, reader); break; } case TRANSFORMER_CLASS_NAME: { handleElementText(reader, element, divertAdd); break; } case EXCLUSIVE: { handleElementText(reader, element, divertAdd); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } if(!required.isEmpty()) { throw missingRequired(reader, required); } list.add(divertAdd); } static void unhandledElement(XMLExtendedStreamReader reader, Element element) throws XMLStreamException { throw MessagingLogger.ROOT_LOGGER.ignoringUnhandledElement(element, reader.getLocation().toString()); } static void handleElementText(final XMLExtendedStreamReader reader, final Element element, final ModelNode node) throws XMLStreamException { handleElementText(reader, element, null, node); } static void handleElementText(final XMLExtendedStreamReader reader, final Element element, final String modelName, final ModelNode node) throws XMLStreamException { AttributeDefinition attributeDefinition = modelName == null ? element.getDefinition() : element.getDefinition(modelName); if (attributeDefinition != null) { final String value = reader.getElementText(); if (attributeDefinition instanceof SimpleAttributeDefinition) { ((SimpleAttributeDefinition) attributeDefinition).parseAndSetParameter(value, node, reader); } else if (attributeDefinition instanceof ListAttributeDefinition) { ((ListAttributeDefinition) attributeDefinition).parseAndAddParameterElement(value, node, reader); } } else { handleElementText(reader, element, node, ModelType.STRING, true, false); } } static void skipElementText(final XMLExtendedStreamReader reader) throws XMLStreamException { reader.getElementText(); } /** @deprecated use AttributeDefinition */ @Deprecated static void handleElementText(final XMLExtendedStreamReader reader, final Element element, final ModelNode node, final ModelType expectedType, final boolean allowNull, final boolean allowExpression) throws XMLStreamException { final String value = reader.getElementText(); if(value != null && value.length() > 0) { ModelNode toSet = node.get(element.getLocalName()); ModelNode modelValue = allowExpression ? parsePossibleExpression(value.trim()) : new ModelNode().set(value.trim()); if (!allowExpression || modelValue.getType() != ModelType.EXPRESSION) { toSet.set(modelValue); } else { try { switch (expectedType) { case BOOLEAN: toSet.set(modelValue.asBoolean()); break; case BIG_DECIMAL: toSet.set(modelValue.asBigDecimal()); break; case BIG_INTEGER: toSet.set(modelValue.asBigInteger()); break; case BYTES: toSet.set(modelValue.asBytes()); break; case DOUBLE: toSet.set(modelValue.asDouble()); break; case INT: toSet.set(modelValue.asInt()); break; case LONG: toSet.set(modelValue.asLong()); break; case STRING: toSet.set(modelValue.asString()); break; default: throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.illegalValue(value, element.getLocalName()), reader.getLocation()); } } catch (IllegalArgumentException iae) { throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.illegalValue(value, element.getLocalName(), expectedType), reader.getLocation()); } } } else if (!allowNull) { throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.illegalValue(value, element.getLocalName()), reader.getLocation()); } } static void processJMSTopic(final XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { final String name = reader.getAttributeValue(0); if(name == null) { throw missingRequired(reader, Collections.singleton("name")); } final ModelNode topic = new ModelNode(); topic.get(OP).set(ADD); topic.get(OP_ADDR).set(address).add(JMS_TOPIC, name); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch(element) { case ENTRY: { final String entry = readStringAttributeElement(reader, CommonAttributes.NAME); CommonAttributes.DESTINATION_ENTRIES.parseAndAddParameterElement(entry, topic, reader); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } updates.add(topic); } static void processJMSQueue(final XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); final String name = reader.getAttributeValue(0); final ModelNode queue = new ModelNode(); queue.get(OP).set(ADD); queue.get(OP_ADDR).set(address).add(JMS_QUEUE, name); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); switch(element) { case ENTRY: { final String entry = readStringAttributeElement(reader, CommonAttributes.NAME); CommonAttributes.DESTINATION_ENTRIES.parseAndAddParameterElement(entry, queue, reader); break; } case SELECTOR: { if(queue.has(SELECTOR.getName())) { throw ParseUtils.duplicateNamedElement(reader, Element.SELECTOR.getLocalName()); } requireSingleAttribute(reader, CommonAttributes.STRING); final String selector = readStringAttributeElement(reader, CommonAttributes.STRING); SELECTOR.parseAndSetParameter(selector, queue, reader); break; } case DURABLE: { if(queue.has(DURABLE.getName())) { throw ParseUtils.duplicateNamedElement(reader, Element.DURABLE.getLocalName()); } handleElementText(reader, element, queue); break; } default: { throw ParseUtils.unexpectedElement(reader); } } } updates.add(queue); } void processConnectionFactory(final XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { requireSingleAttribute(reader, CommonAttributes.NAME); final String name = reader.getAttributeValue(0); final ModelNode connectionFactory = new ModelNode(); connectionFactory.get(OP).set(ADD); connectionFactory.get(OP_ADDR).set(address).add(CONNECTION_FACTORY, name); updates.add(createConnectionFactory(reader, connectionFactory, false)); } void processPooledConnectionFactory(final XMLExtendedStreamReader reader, ModelNode address, List<ModelNode> updates) throws XMLStreamException { final String name = reader.getAttributeValue(0); if(name == null) { throw missingRequired(reader, Collections.singleton("name")); } final ModelNode connectionFactory = new ModelNode(); connectionFactory.get(OP).set(ADD); connectionFactory.get(OP_ADDR).set(address).add(POOLED_CONNECTION_FACTORY, name); updates.add(createConnectionFactory(reader, connectionFactory, true)); } static ModelNode processJmsConnectors(final XMLExtendedStreamReader reader) throws XMLStreamException { final ModelNode connectors = new ModelNode(); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { String name = null; int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case CONNECTOR_NAME: { name = value.trim(); break; } case BACKUP_CONNECTOR_NAME: { MessagingLogger.ROOT_LOGGER.deprecatedXMLAttribute(attribute.toString()); break; } default: { throw ParseUtils.unexpectedAttribute(reader, i); } } } if(name == null) { throw ParseUtils.missingRequired(reader, Collections.singleton(Attribute.CONNECTOR_NAME)); } final Element element = Element.forName(reader.getLocalName()); if(element != Element.CONNECTOR_REF) { throw ParseUtils.unexpectedElement(reader); } ParseUtils.requireNoContent(reader); // create the connector node connectors.get(name); } return connectors; } protected ModelNode createConnectionFactory(XMLExtendedStreamReader reader, ModelNode connectionFactory, boolean pooled) throws XMLStreamException { Set<Element> seen = EnumSet.noneOf(Element.class); while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element = Element.forName(reader.getLocalName()); if (!seen.add(element)) { throw ParseUtils.duplicateNamedElement(reader, element.getLocalName()); } switch(element) { // ========================================================= // elements common to regular & pooled connection factories case DISCOVERY_GROUP_REF: { checkOtherElementIsNotAlreadyDefined(reader, seen, Element.DISCOVERY_GROUP_REF, Element.CONNECTORS); final String groupRef = readStringAttributeElement(reader, Common.DISCOVERY_GROUP_NAME.getXmlName()); Common.DISCOVERY_GROUP_NAME.parseAndSetParameter(groupRef, connectionFactory, reader); break; } case CONNECTORS: { checkOtherElementIsNotAlreadyDefined(reader, seen, Element.CONNECTORS, Element.DISCOVERY_GROUP_REF); connectionFactory.get(CONNECTOR).set(processJmsConnectors(reader)); break; } case ENTRIES: { while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element local = Element.forName(reader.getLocalName()); if(local != Element.ENTRY ) { throw ParseUtils.unexpectedElement(reader); } final String entry = readStringAttributeElement(reader, CommonAttributes.NAME); Common.ENTRIES.parseAndAddParameterElement(entry, connectionFactory, reader); } break; } case HA: case CLIENT_FAILURE_CHECK_PERIOD: case CALL_TIMEOUT: case CONSUMER_WINDOW_SIZE: case CONSUMER_MAX_RATE: case PRODUCER_WINDOW_SIZE: case PRODUCER_MAX_RATE: case CACHE_LARGE_MESSAGE_CLIENT: case CLIENT_ID: case DUPS_OK_BATCH_SIZE: case TRANSACTION_BATH_SIZE: case BLOCK_ON_ACK: case BLOCK_ON_NON_DURABLE_SEND: case BLOCK_ON_DURABLE_SEND: case AUTO_GROUP: case PRE_ACK: case FAILOVER_ON_INITIAL_CONNECTION: case FAILOVER_ON_SERVER_SHUTDOWN: case LOAD_BALANCING_CLASS_NAME: case USE_GLOBAL_POOLS: case GROUP_ID: handleElementText(reader, element, connectionFactory); break; case CONFIRMATION_WINDOW_SIZE: case CONNECTION_TTL: case MAX_RETRY_INTERVAL: case MIN_LARGE_MESSAGE_SIZE: case RECONNECT_ATTEMPTS: case RETRY_INTERVAL: case RETRY_INTERVAL_MULTIPLIER: case SCHEDULED_THREAD_POOL_MAX_SIZE: case THREAD_POOL_MAX_SIZE: // Use the "connection" variant handleElementText(reader, element, "connection", connectionFactory); break; case DISCOVERY_INITIAL_WAIT_TIMEOUT: MessagingLogger.ROOT_LOGGER.deprecatedXMLElement(element.toString()); skipElementText(reader); break; // end of common elements // ========================================================= // ========================================================= // elements specific to regular (non-pooled) connection factories case CONNECTION_FACTORY_TYPE: if(pooled) { throw unexpectedElement(reader); } handleElementText(reader, element, connectionFactory); break; // end of regular CF elements // ========================================================= // ========================================================= // elements specific to pooled connection factories case INBOUND_CONFIG: { if(!pooled) { throw unexpectedElement(reader); } while(reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element local = Element.forName(reader.getLocalName()); switch (local) { case USE_JNDI: case JNDI_PARAMS: case USE_LOCAL_TX: case SETUP_ATTEMPTS: case SETUP_INTERVAL: handleElementText(reader, local, connectionFactory); break; default: throw unexpectedElement(reader); } } break; } case TRANSACTION: { if(!pooled) { throw ParseUtils.unexpectedElement(reader); } final String txType = reader.getAttributeValue(0); if( txType != null) { connectionFactory.get(Pooled.TRANSACTION.getName()).set(txType); } ParseUtils.requireNoContent(reader); break; } case USER: if(!pooled) { throw unexpectedElement(reader); } // Element name is overloaded, handleElementText can not be used, we must use the correct attribute Pooled.USER.parseAndSetParameter(reader.getElementText(), connectionFactory, reader); break; case PASSWORD: if(!pooled) { throw unexpectedElement(reader); } // Element name is overloaded, handleElementText can not be used, we must use the correct attribute Pooled.PASSWORD.parseAndSetParameter(reader.getElementText(), connectionFactory, reader); break; // end of pooled CF elements // ========================================================= default: { handleUnknownConnectionFactoryAttribute(reader, element, connectionFactory, pooled); } } } checkOnlyOneOfElements(reader, seen, Element.CONNECTORS, Element.DISCOVERY_GROUP_REF); return connectionFactory; } protected void handleUnknownConnectionFactoryAttribute(XMLExtendedStreamReader reader, Element element, ModelNode connectionFactory, boolean pooled) throws XMLStreamException { throw ParseUtils.unexpectedElement(reader); } protected void checkOtherElementIsNotAlreadyDefined(XMLStreamReader reader, Set<Element> seen, Element currentElement, Element otherElement) throws XMLStreamException { if (seen.contains(otherElement)) { throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.illegalElement(currentElement.getLocalName(), otherElement.getLocalName()), reader.getLocation()); } } /** * Check one and only one of the 2 elements has been defined */ protected static void checkOnlyOneOfElements(XMLExtendedStreamReader reader, Set<Element> seen, Element element1, Element element2) throws XMLStreamException { if (!seen.contains(element1) && !seen.contains(element2)) { throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.required(element1.getLocalName(), element2.getLocalName()), reader.getLocation()); } if (seen.contains(element1) && seen.contains(element2)) { throw new XMLStreamException(MessagingLogger.ROOT_LOGGER.onlyOneRequired(element1.getLocalName(), element2.getLocalName()), reader.getLocation()); } } }