/* * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.switchyard.as7.extension; 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.descriptions.ModelDescriptionConstants.SUBSYSTEM; import static org.jboss.as.controller.parsing.ParseUtils.missingRequired; 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.unexpectedAttribute; import static org.jboss.as.controller.parsing.ParseUtils.unexpectedElement; import static org.switchyard.as7.extension.CommonAttributes.EXTENSION; import static org.switchyard.as7.extension.CommonAttributes.IMPLCLASS; import static org.switchyard.as7.extension.CommonAttributes.MODULE; import static org.switchyard.as7.extension.CommonAttributes.PROPERTIES; import static org.switchyard.as7.extension.CommonAttributes.SECURITY_CONFIG; import static org.switchyard.as7.extension.CommonAttributes.SOCKET_BINDING; import java.util.Collections; import java.util.List; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.dmr.ModelNode; import org.jboss.staxmapper.XMLElementReader; import org.jboss.staxmapper.XMLExtendedStreamReader; /** * A SwitchYard subsystem reader/parser. * * @author Magesh Kumar B <mageshbk@jboss.com> (C) 2012 Red Hat Inc. */ final class SwitchYardSubsystemReader implements XMLStreamConstants, XMLElementReader<List<ModelNode>> { private static final SwitchYardSubsystemReader INSTANCE = new SwitchYardSubsystemReader(); private SwitchYardSubsystemReader() { // forbidden instantiation } static SwitchYardSubsystemReader getInstance() { return INSTANCE; } /** {@inheritDoc} */ @Override public void readElement(final XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { // Require no attributes requireNoAttributes(reader); // Add our subsystem's 'add' operation ModelNode subsystem = SwitchYardExtension.createAddSubsystemOperation(); list.add(subsystem); // Elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (reader.getNamespaceURI().equals(SwitchYardExtension.NAMESPACE)) { final Element element = Element.forName(reader.getLocalName()); switch (element) { case SOCKET_BINDING: String sockets = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case NAMES: sockets = reader.getAttributeValue(i); break; default: throw unexpectedAttribute(reader, i); } } if (sockets != null) { subsystem.get(SOCKET_BINDING).set(sockets); } requireNoContent(reader); break; case SECURITY_CONFIGS: parseSecurityConfigsElement(reader, list); break; case MODULES: parseModulesElement(reader, list); break; case EXTENSIONS: parseExtensionsElement(reader, list); break; case PROPERTIES: ModelNode properties = parsePropertiesElement("", reader); if (properties != null) { subsystem.get(PROPERTIES).set(properties); } break; default: throw unexpectedElement(reader); } } } } void parseSecurityConfigsElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { // Handle attributes requireNoAttributes(reader); // Handle module elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (reader.getNamespaceURI().equals(SwitchYardExtension.NAMESPACE)) { final Element element = Element.forName(reader.getLocalName()); if (element == Element.SECURITY_CONFIG) { parseSecurityConfigElement(reader, list); } else { throw unexpectedElement(reader); } } } } void parseSecurityConfigElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { String identifier = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case IDENTIFIER: identifier = reader.getAttributeValue(i); break; default: throw unexpectedAttribute(reader, i); } } if (identifier == null) { throw missingRequired(reader, Collections.singleton(Attribute.IDENTIFIER)); } //Add the 'add' operation for each 'security-config' child ModelNode securityConfigAdd = new ModelNode(); securityConfigAdd.get(OP).set(ModelDescriptionConstants.ADD); PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, SwitchYardExtension.SUBSYSTEM_NAME), PathElement.pathElement(SECURITY_CONFIG, identifier)); securityConfigAdd.get(OP_ADDR).set(addr.toModelNode()); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element1 = Element.forName(reader.getLocalName()); switch (element1) { case PROPERTIES: ModelNode properties = parsePropertiesElement(identifier, reader); if (properties != null) { securityConfigAdd.get(PROPERTIES).set(properties); } break; default: throw unexpectedElement(reader); } } list.add(securityConfigAdd); } void parseModulesElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { // Handle attributes requireNoAttributes(reader); // Handle module elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (reader.getNamespaceURI().equals(SwitchYardExtension.NAMESPACE)) { final Element element = Element.forName(reader.getLocalName()); if (element == Element.MODULE) { parseModuleElement(reader, list); } else { throw unexpectedElement(reader); } } } } void parseModuleElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { String identifier = null; String implClass = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case IDENTIFIER: identifier = reader.getAttributeValue(i); break; case IMPLCLASS: implClass = reader.getAttributeValue(i); break; default: throw unexpectedAttribute(reader, i); } } if (identifier == null) { throw missingRequired(reader, Collections.singleton(Attribute.IDENTIFIER)); } if (implClass == null) { throw missingRequired(reader, Collections.singleton(Attribute.IMPLCLASS)); } //Add the 'add' operation for each 'module' child ModelNode moduleAdd = new ModelNode(); moduleAdd.get(OP).set(ModelDescriptionConstants.ADD); PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, SwitchYardExtension.SUBSYSTEM_NAME), PathElement.pathElement(MODULE, identifier)); moduleAdd.get(OP_ADDR).set(addr.toModelNode()); moduleAdd.get(IMPLCLASS).set(implClass); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { final Element element1 = Element.forName(reader.getLocalName()); switch (element1) { case PROPERTIES: ModelNode properties = parsePropertiesElement(identifier, reader); if (properties != null) { moduleAdd.get(PROPERTIES).set(properties); } break; default: throw unexpectedElement(reader); } } list.add(moduleAdd); } ModelNode parsePropertiesElement(String identifier, XMLExtendedStreamReader reader) throws XMLStreamException { // Handle attributes requireNoAttributes(reader); ModelNode properties = new ModelNode(); StringBuffer configModel = new StringBuffer(); // Handle elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (reader.getNamespaceURI().equals(SwitchYardExtension.NAMESPACE)) { final Element element = Element.forName(reader.getLocalName()); String name = reader.getLocalName(); String value = reader.getElementText(); if (properties.has(name)) { throw ExtensionMessages.MESSAGES.alreadyDeclared(element.getLocalName(), reader.getLocation().toString()); } ModelNode property = new ModelNode(); property.set(value); properties.get(name).set(property); configModel.append(element.toString()); } } return properties; } void parseExtensionsElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { // Handle attributes requireNoAttributes(reader); // Handle module elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (reader.getNamespaceURI().equals(SwitchYardExtension.NAMESPACE)) { final Element element = Element.forName(reader.getLocalName()); if (element == Element.EXTENSION) { parseExtensionElement(reader, list); } else { throw unexpectedElement(reader); } } } } void parseExtensionElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { String identifier = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { requireNoNamespaceAttribute(reader, i); final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case IDENTIFIER: identifier = reader.getAttributeValue(i); break; default: throw unexpectedAttribute(reader, i); } } if (identifier == null) { throw missingRequired(reader, Collections.singleton(Attribute.IDENTIFIER)); } //Add the 'add' operation for each 'module' child ModelNode moduleAdd = new ModelNode(); moduleAdd.get(OP).set(ModelDescriptionConstants.ADD); PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, SwitchYardExtension.SUBSYSTEM_NAME), PathElement.pathElement(EXTENSION, identifier)); moduleAdd.get(OP_ADDR).set(addr.toModelNode()); while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { throw unexpectedElement(reader); } list.add(moduleAdd); } }