StandardExtensionElement.java
- /**
- *
- * Copyright 2015-2021 Florian Schmaus.
- *
- * 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.jivesoftware.smack.packet;
- import java.util.Collections;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import javax.xml.namespace.QName;
- import org.jivesoftware.smack.util.MultiMap;
- import org.jivesoftware.smack.util.Objects;
- import org.jivesoftware.smack.util.StringUtils;
- import org.jivesoftware.smack.util.XmlStringBuilder;
- /**
- * An {@link ExtensionElement} modeling the often required and used XML features when using XMPP. It
- * is therefore suitable for most use cases. Use
- * {@link StandardExtensionElement#builder(String, String)} to build these elements.
- * <p>
- * Note the this is only meant as catch-all if no particular extension element provider is
- * registered. Protocol implementations should prefer to model their own extension elements tailored
- * to their use cases.
- * </p>
- *
- * @since 4.2
- * @author Florian Schmaus
- */
- public final class StandardExtensionElement implements XmlElement {
- private final String name;
- private final String namespace;
- private final Map<String, String> attributes;
- private final String text;
- private final MultiMap<QName, StandardExtensionElement> elements;
- private XmlStringBuilder xmlCache;
- /**
- * Constructs a new extension element with the given name and namespace and nothing else.
- * <p>
- * This is meant to construct extension elements used as simple flags in Stanzas.
- * <p>
- *
- * @param name the name of the extension element.
- * @param namespace the namespace of the extension element.
- */
- public StandardExtensionElement(String name, String namespace) {
- this(name, namespace, null, null, null);
- }
- private StandardExtensionElement(String name, String namespace, Map<String, String> attributes, String text,
- MultiMap<QName, StandardExtensionElement> elements) {
- this.name = StringUtils.requireNotNullNorEmpty(name, "Name must not be null nor empty");
- this.namespace = StringUtils.requireNotNullNorEmpty(namespace, "Namespace must not be null nor empty");
- if (attributes == null) {
- this.attributes = Collections.emptyMap();
- }
- else {
- this.attributes = attributes;
- }
- this.text = text;
- this.elements = elements;
- }
- @Override
- public String getElementName() {
- return name;
- }
- @Override
- public String getNamespace() {
- return namespace;
- }
- public String getAttributeValue(String attribute) {
- return attributes.get(attribute);
- }
- public Map<String, String> getAttributes() {
- return Collections.unmodifiableMap(attributes);
- }
- public StandardExtensionElement getFirstElement(String element, String namespace) {
- if (elements == null) {
- return null;
- }
- QName key = new QName(namespace, element);
- return elements.getFirst(key);
- }
- public StandardExtensionElement getFirstElement(String element) {
- return getFirstElement(element, namespace);
- }
- public List<StandardExtensionElement> getElements(String element, String namespace) {
- if (elements == null) {
- return null;
- }
- QName key = new QName(namespace, element);
- return elements.getAll(key);
- }
- public List<StandardExtensionElement> getElements(String element) {
- return getElements(element, namespace);
- }
- public List<StandardExtensionElement> getElements() {
- if (elements == null) {
- return Collections.emptyList();
- }
- return elements.values();
- }
- public String getText() {
- return text;
- }
- @Override
- public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
- if (xmlCache != null) {
- return xmlCache;
- }
- XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
- for (Map.Entry<String, String> entry : attributes.entrySet()) {
- xml.attribute(entry.getKey(), entry.getValue());
- }
- xml.rightAngleBracket();
- if (text != null) {
- xml.text(text);
- }
- if (elements != null) {
- for (Map.Entry<QName, StandardExtensionElement> entry : elements.entrySet()) {
- xml.append(entry.getValue().toXML(getNamespace()));
- }
- }
- xml.closeElement(this);
- xmlCache = xml;
- return xml;
- }
- public static Builder builder(String name, String namespace) {
- return new Builder(name, namespace);
- }
- public static final class Builder {
- private final String name;
- private final String namespace;
- private Map<String, String> attributes;
- private String text;
- private MultiMap<QName, StandardExtensionElement> elements;
- private Builder(String name, String namespace) {
- this.name = name;
- this.namespace = namespace;
- }
- public Builder addAttribute(String name, String value) {
- StringUtils.requireNotNullNorEmpty(name, "Attribute name must be set");
- Objects.requireNonNull(value, "Attribute value must be not null");
- if (attributes == null) {
- attributes = new LinkedHashMap<>();
- }
- attributes.put(name, value);
- return this;
- }
- public Builder addAttributes(Map<String, String> attributes) {
- if (this.attributes == null) {
- this.attributes = new LinkedHashMap<>(attributes.size());
- }
- this.attributes.putAll(attributes);
- return this;
- }
- public Builder setText(String text) {
- this.text = Objects.requireNonNull(text, "Text must be not null");
- return this;
- }
- public Builder addElement(StandardExtensionElement element) {
- Objects.requireNonNull(element, "Element must not be null");
- if (elements == null) {
- elements = new MultiMap<>();
- }
- QName key = element.getQName();
- elements.put(key, element);
- return this;
- }
- public Builder addElement(String name, String textValue) {
- StandardExtensionElement element = StandardExtensionElement.builder(name, this.namespace).setText(
- textValue).build();
- return addElement(element);
- }
- public StandardExtensionElement build() {
- return new StandardExtensionElement(name, namespace, attributes, text, elements);
- }
- }
- }