package org.zwobble.mammoth.internal.xml; import org.zwobble.mammoth.internal.util.Iterables; import java.util.List; import java.util.Map; import java.util.Optional; import static org.zwobble.mammoth.internal.util.Iterables.*; import static org.zwobble.mammoth.internal.util.Lists.toList; import static org.zwobble.mammoth.internal.util.Maps.lookup; public class XmlElement implements XmlNode, XmlElementLike { private final String name; private final Map attributes; private final List children; public XmlElement(String name, Map attributes, List children) { this.name = name; this.attributes = attributes; this.children = children; } public String getName() { return name; } public Map getAttributes() { return attributes; } public String getAttribute(String name) { return getAttributeOrNone(name) .orElseThrow(() -> new RuntimeException("Element has no '" + name + "' attribute")); } @Override public Optional getAttributeOrNone(String name) { return lookup(attributes, name); } @Override public String innerText() { return String.join("", lazyMap(children, XmlNode::innerText)); } @Override public T accept(XmlNodeVisitor visitor) { return visitor.visit(this); } @Override public List getChildren() { return children; } @Override public String toString() { return "XmlElement(name=" + name + ", attributes=" + attributes + ", children=" + children + ")"; } public XmlElementList findChildren(String name) { return new XmlElementList(toList(findChildrenIterable(name))); } public Optional findChild(String name) { return Iterables.getFirst(findChildrenIterable(name)); } @Override public boolean hasChild(String name) { return findChildrenIterable(name).iterator().hasNext(); } @Override public XmlElementLike findChildOrEmpty(String name) { return getFirst(findChildrenIterable(name), NullXmlElement.INSTANCE); } private Iterable findChildrenIterable(String name) { return lazyFilter( lazyFilter(children, XmlElement.class), child -> child.getName().equals(name)); } }