1package eu.siacs.conversations.xml;
2
3import java.util.ArrayList;
4import java.util.Hashtable;
5import java.util.List;
6
7import eu.siacs.conversations.utils.XmlHelper;
8import eu.siacs.conversations.xmpp.InvalidJid;
9import eu.siacs.conversations.xmpp.Jid;
10import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
11
12public class Element {
13 private final String name;
14 private Hashtable<String, String> attributes = new Hashtable<>();
15 private String content;
16 protected List<Element> children = new ArrayList<>();
17
18 public Element(String name) {
19 this.name = name;
20 }
21
22 public Element(String name, String xmlns) {
23 this.name = name;
24 this.setAttribute("xmlns", xmlns);
25 }
26
27 public Element addChild(Element child) {
28 this.content = null;
29 children.add(child);
30 return child;
31 }
32
33 public Element addChild(String name) {
34 this.content = null;
35 Element child = new Element(name);
36 children.add(child);
37 return child;
38 }
39
40 public Element addChild(String name, String xmlns) {
41 this.content = null;
42 Element child = new Element(name);
43 child.setAttribute("xmlns", xmlns);
44 children.add(child);
45 return child;
46 }
47
48 public Element setContent(String content) {
49 this.content = content;
50 this.children.clear();
51 return this;
52 }
53
54 public Element findChild(String name) {
55 for (Element child : this.children) {
56 if (child.getName().equals(name)) {
57 return child;
58 }
59 }
60 return null;
61 }
62
63 public String findChildContent(String name) {
64 Element element = findChild(name);
65 return element == null ? null : element.getContent();
66 }
67
68 public LocalizedContent findInternationalizedChildContentInDefaultNamespace(String name) {
69 return LocalizedContent.get(this, name);
70 }
71
72 public Element findChild(String name, String xmlns) {
73 for (Element child : this.children) {
74 if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
75 return child;
76 }
77 }
78 return null;
79 }
80
81 public Element findChildEnsureSingle(String name, String xmlns) {
82 final List<Element> results = new ArrayList<>();
83 for (Element child : this.children) {
84 if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
85 results.add(child);
86 }
87 }
88 if (results.size() == 1) {
89 return results.get(0);
90 }
91 return null;
92 }
93
94 public String findChildContent(String name, String xmlns) {
95 Element element = findChild(name,xmlns);
96 return element == null ? null : element.getContent();
97 }
98
99 public boolean hasChild(final String name) {
100 return findChild(name) != null;
101 }
102
103 public boolean hasChild(final String name, final String xmlns) {
104 return findChild(name, xmlns) != null;
105 }
106
107 public List<Element> getChildren() {
108 return this.children;
109 }
110
111 public Element setChildren(List<Element> children) {
112 this.children = children;
113 return this;
114 }
115
116 public final String getContent() {
117 return content;
118 }
119
120 public Element setAttribute(String name, String value) {
121 if (name != null && value != null) {
122 this.attributes.put(name, value);
123 }
124 return this;
125 }
126
127 public Element setAttribute(String name, Jid value) {
128 if (name != null && value != null) {
129 this.attributes.put(name, value.toEscapedString());
130 }
131 return this;
132 }
133
134 public Element removeAttribute(String name) {
135 this.attributes.remove(name);
136 return this;
137 }
138
139 public Element setAttributes(Hashtable<String, String> attributes) {
140 this.attributes = attributes;
141 return this;
142 }
143
144 public String getAttribute(String name) {
145 if (this.attributes.containsKey(name)) {
146 return this.attributes.get(name);
147 } else {
148 return null;
149 }
150 }
151
152 public Jid getAttributeAsJid(String name) {
153 final String jid = this.getAttribute(name);
154 if (jid != null && !jid.isEmpty()) {
155 try {
156 return Jid.ofEscaped(jid);
157 } catch (final IllegalArgumentException e) {
158 return InvalidJid.of(jid, this instanceof MessagePacket);
159 }
160 }
161 return null;
162 }
163
164 public Hashtable<String, String> getAttributes() {
165 return this.attributes;
166 }
167
168 public String toString() {
169 StringBuilder elementOutput = new StringBuilder();
170 if ((content == null) && (children.size() == 0)) {
171 Tag emptyTag = Tag.empty(name);
172 emptyTag.setAtttributes(this.attributes);
173 elementOutput.append(emptyTag.toString());
174 } else {
175 Tag startTag = Tag.start(name);
176 startTag.setAtttributes(this.attributes);
177 elementOutput.append(startTag);
178 if (content != null) {
179 elementOutput.append(XmlHelper.encodeEntities(content));
180 } else {
181 for (Element child : children) {
182 elementOutput.append(child.toString());
183 }
184 }
185 Tag endTag = Tag.end(name);
186 elementOutput.append(endTag);
187 }
188 return elementOutput.toString();
189 }
190
191 public final String getName() {
192 return name;
193 }
194
195 public void clearChildren() {
196 this.children.clear();
197 }
198
199 public void setAttribute(String name, long value) {
200 this.setAttribute(name, Long.toString(value));
201 }
202
203 public void setAttribute(String name, int value) {
204 this.setAttribute(name, Integer.toString(value));
205 }
206
207 public boolean getAttributeAsBoolean(String name) {
208 String attr = getAttribute(name);
209 return (attr != null && (attr.equalsIgnoreCase("true") || attr.equalsIgnoreCase("1")));
210 }
211
212 public String getNamespace() {
213 return getAttribute("xmlns");
214 }
215}