/* * Copyright 2016 Red Hat, Inc. * * 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.wildfly.extension.batch.jberet; import java.util.EnumMap; import java.util.EnumSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.xml.stream.XMLStreamException; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.AttributeParser; import org.jboss.as.controller.parsing.ParseUtils; import org.jboss.dmr.ModelNode; import org.jboss.staxmapper.XMLExtendedStreamReader; /** * Attribute parsing utilities. * * @author <a href="mailto:jperkins@redhat.com">James R. Perkins</a> */ class AttributeParsers { /** * An attribute parser for elements with a single {@code value} that don't allow any content within the element. */ static final AttributeParser VALUE = new AttributeParser() { @Override public void parseElement(final AttributeDefinition attribute, final XMLExtendedStreamReader reader, final ModelNode operation) throws XMLStreamException { operation.get(attribute.getName()).set(readValueAttribute(reader)); ParseUtils.requireNoContent(reader); } @Override public boolean isParseAsElement() { return true; } }; /** * Reads a {@code name} attribute on an element. * * @param reader the reader used to read the attribute with * * @return the name attribute or {@code null} if the name attribute was not defined * * @throws XMLStreamException if an XML processing error occurs */ static String readNameAttribute(final XMLExtendedStreamReader reader) throws XMLStreamException { return readRequiredAttributes(reader, EnumSet.of(Attribute.NAME)).get(Attribute.NAME); } /** * Reads a {@code value} attribute on an element. * * @param reader the reader used to read the attribute with * * @return the value attribute or {@code null} if the value attribute was not defined * * @throws XMLStreamException if an XML processing error occurs */ static String readValueAttribute(final XMLExtendedStreamReader reader) throws XMLStreamException { return readRequiredAttributes(reader, EnumSet.of(Attribute.VALUE)).get(Attribute.VALUE); } /** * Reads the required attributes from an XML configuration. * <p> * The reader must be on an element with attributes. * </p> * * @param reader the reader for the attributes * @param attributes the required attributes * * @return a map of the required attributes with the key being the attribute and the value being the value of the * attribute * * @throws XMLStreamException if an XML processing error occurs */ static Map<Attribute, String> readRequiredAttributes(final XMLExtendedStreamReader reader, final Set<Attribute> attributes) throws XMLStreamException { final int attributeCount = reader.getAttributeCount(); final Map<Attribute, String> result = new EnumMap<>(Attribute.class); for (int i = 0; i < attributeCount; i++) { final Attribute current = Attribute.forName(reader.getAttributeLocalName(i)); if (attributes.contains(current)) { if (result.put(current, reader.getAttributeValue(i)) != null) { throw ParseUtils.duplicateAttribute(reader, current.getLocalName()); } } else { throw ParseUtils.unexpectedAttribute(reader, i, attributes.stream().map(Attribute::getLocalName).collect(Collectors.toSet())); } } if (result.isEmpty()) { throw ParseUtils.missingRequired(reader, attributes.stream().map(Attribute::getLocalName).collect(Collectors.toSet())); } return result; } }