1package eu.siacs.conversations.xml;
2
3import android.support.annotation.NonNull;
4import android.util.Log;
5
6import java.util.ArrayList;
7import java.util.HashMap;
8import java.util.Hashtable;
9import java.util.List;
10import java.util.Locale;
11
12import eu.siacs.conversations.Config;
13import eu.siacs.conversations.utils.XmlHelper;
14import eu.siacs.conversations.xmpp.InvalidJid;
15import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
16import rocks.xmpp.addr.Jid;
17
18public class Element {
19 private final String name;
20 private Hashtable<String, String> attributes = new Hashtable<>();
21 private String content;
22 protected List<Element> children = new ArrayList<>();
23
24 public Element(String name) {
25 this.name = name;
26 }
27
28 public Element(String name, String xmlns) {
29 this.name = name;
30 this.setAttribute("xmlns", xmlns);
31 }
32
33 public Element addChild(Element child) {
34 this.content = null;
35 children.add(child);
36 return child;
37 }
38
39 public Element addChild(String name) {
40 this.content = null;
41 Element child = new Element(name);
42 children.add(child);
43 return child;
44 }
45
46 public Element addChild(String name, String xmlns) {
47 this.content = null;
48 Element child = new Element(name);
49 child.setAttribute("xmlns", xmlns);
50 children.add(child);
51 return child;
52 }
53
54 public Element setContent(String content) {
55 this.content = content;
56 this.children.clear();
57 return this;
58 }
59
60 public Element findChild(String name) {
61 for (Element child : this.children) {
62 if (child.getName().equals(name)) {
63 return child;
64 }
65 }
66 return null;
67 }
68
69 public String findChildContent(String name) {
70 Element element = findChild(name);
71 return element == null ? null : element.getContent();
72 }
73
74 public String findInternationalizedChildContent(String name) {
75 return findInternationalizedChildContent(name, Locale.getDefault().getLanguage());
76 }
77
78 public String findInternationalizedChildContent(String name,@NonNull String language) {
79 HashMap<String,String> contents = new HashMap<>();
80 for(Element child : this.children) {
81 if (name.equals(child.getName())) {
82 String lang = child.getAttribute("xml:lang");
83 String content = child.getContent();
84 if (content != null) {
85 if (language.equals(lang)) {
86 return content;
87 } else {
88 contents.put(lang, content);
89 }
90 }
91 }
92 }
93
94 return contents.get(null);
95 }
96
97 public Element findChild(String name, String xmlns) {
98 for (Element child : this.children) {
99 if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
100 return child;
101 }
102 }
103 return null;
104 }
105
106 public String findChildContent(String name, String xmlns) {
107 Element element = findChild(name,xmlns);
108 return element == null ? null : element.getContent();
109 }
110
111 public boolean hasChild(final String name) {
112 return findChild(name) != null;
113 }
114
115 public boolean hasChild(final String name, final String xmlns) {
116 return findChild(name, xmlns) != null;
117 }
118
119 public List<Element> getChildren() {
120 return this.children;
121 }
122
123 public Element setChildren(List<Element> children) {
124 this.children = children;
125 return this;
126 }
127
128 public final String getContent() {
129 return content;
130 }
131
132 public Element setAttribute(String name, String value) {
133 if (name != null && value != null) {
134 this.attributes.put(name, value);
135 }
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}