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