1
15
16 package software.amazon.awssdk.protocols.query.unmarshall;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Optional;
24 import software.amazon.awssdk.annotations.SdkProtectedApi;
25 import software.amazon.awssdk.core.exception.SdkClientException;
26
27
30 @SdkProtectedApi
31 public final class XmlElement {
32
33 private static final XmlElement EMPTY = XmlElement.builder().elementName("eof").build();
34
35 private final String elementName;
36 private final HashMap<String, List<XmlElement>> childrenByElement;
37 private final List<XmlElement> children;
38 private final String textContent;
39 private final Map<String, String> attributes;
40
41 private XmlElement(Builder builder) {
42 this.elementName = builder.elementName;
43 this.childrenByElement = new HashMap<>(builder.childrenByElement);
44 this.children = Collections.unmodifiableList(new ArrayList<>(builder.children));
45 this.textContent = builder.textContent;
46 this.attributes = Collections.unmodifiableMap(new HashMap<>(builder.attributes));
47 }
48
49
52 public String elementName() {
53 return elementName;
54 }
55
56
59 public List<XmlElement> children() {
60 return children;
61 }
62
63
66 public XmlElement getFirstChild() {
67 return children.isEmpty() ? null : children.get(0);
68 }
69
70
76 public List<XmlElement> getElementsByName(String tagName) {
77 return childrenByElement.getOrDefault(tagName, Collections.emptyList());
78 }
79
80
87 public XmlElement getElementByName(String tagName) {
88 List<XmlElement> elementsByName = getElementsByName(tagName);
89 if (elementsByName.size() > 1) {
90 throw SdkClientException.create(
91 String.format("Did not expect more than one element with the name %s in the XML event %s",
92 tagName, this.elementName));
93 }
94 return elementsByName.size() == 1 ? elementsByName.get(0) : null;
95 }
96
97
104 public Optional<XmlElement> getOptionalElementByName(String tagName) {
105 return Optional.ofNullable(getElementByName(tagName));
106 }
107
108
111 public String textContent() {
112 return textContent;
113 }
114
115
118 public Optional<String> getOptionalAttributeByName(String attribute) {
119 return Optional.ofNullable(attributes.get(attribute));
120 }
121
122
125 public Map<String, String> attributes() {
126 return attributes;
127 }
128
129
132 public static Builder builder() {
133 return new Builder();
134 }
135
136
139 public static XmlElement empty() {
140 return EMPTY;
141 }
142
143
146 public static final class Builder {
147
148 private String elementName;
149 private final Map<String, List<XmlElement>> childrenByElement = new HashMap<>();
150 private final List<XmlElement> children = new ArrayList<>();
151 private String textContent = "";
152 private Map<String, String> attributes = new HashMap<>();
153
154 private Builder() {
155 }
156
157 public Builder elementName(String elementName) {
158 this.elementName = elementName;
159 return this;
160 }
161
162 public Builder addChildElement(XmlElement childElement) {
163 this.childrenByElement.computeIfAbsent(childElement.elementName(), s -> new ArrayList<>());
164 this.childrenByElement.get(childElement.elementName()).add(childElement);
165 this.children.add(childElement);
166 return this;
167 }
168
169 public Builder textContent(String textContent) {
170 this.textContent = textContent;
171 return this;
172 }
173
174 public Builder attributes(Map<String, String> attributes) {
175 this.attributes = attributes;
176 return this;
177 }
178
179 public XmlElement build() {
180 return new XmlElement(this);
181 }
182 }
183
184 }
185