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 rocks.xmpp.addr.Jid;
15
16public class Element {
17 private final String name;
18 private Hashtable<String, String> attributes = new Hashtable<>();
19 private String content;
20 protected List<Element> children = new ArrayList<>();
21
22 public Element(String name) {
23 this.name = name;
24 }
25
26 public Element(String name, String xmlns) {
27 this.name = name;
28 this.setAttribute("xmlns", xmlns);
29 }
30
31 public Element addChild(Element child) {
32 this.content = null;
33 children.add(child);
34 return child;
35 }
36
37 public Element addChild(String name) {
38 this.content = null;
39 Element child = new Element(name);
40 children.add(child);
41 return child;
42 }
43
44 public Element addChild(String name, String xmlns) {
45 this.content = null;
46 Element child = new Element(name);
47 child.setAttribute("xmlns", xmlns);
48 children.add(child);
49 return child;
50 }
51
52 public Element setContent(String content) {
53 this.content = content;
54 this.children.clear();
55 return this;
56 }
57
58 public Element findChild(String name) {
59 for (Element child : this.children) {
60 if (child.getName().equals(name)) {
61 return child;
62 }
63 }
64 return null;
65 }
66
67 public String findChildContent(String name) {
68 Element element = findChild(name);
69 return element == null ? null : element.getContent();
70 }
71
72 public String findInternationalizedChildContent(String name) {
73 return findInternationalizedChildContent(name, Locale.getDefault().getLanguage());
74 }
75
76 public String findInternationalizedChildContent(String name,@NonNull String language) {
77 HashMap<String,String> contents = new HashMap<>();
78 for(Element child : this.children) {
79 if (name.equals(child.getName())) {
80 String lang = child.getAttribute("xml:lang");
81 String content = child.getContent();
82 if (content != null) {
83 if (language.equals(lang)) {
84 return content;
85 } else {
86 contents.put(lang, content);
87 }
88 }
89 }
90 }
91
92 return contents.get(null);
93 }
94
95 public Element findChild(String name, String xmlns) {
96 for (Element child : this.children) {
97 if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
98 return child;
99 }
100 }
101 return null;
102 }
103
104 public String findChildContent(String name, String xmlns) {
105 Element element = findChild(name,xmlns);
106 return element == null ? null : element.getContent();
107 }
108
109 public boolean hasChild(final String name) {
110 return findChild(name) != null;
111 }
112
113 public boolean hasChild(final String name, final String xmlns) {
114 return findChild(name, xmlns) != null;
115 }
116
117 public List<Element> getChildren() {
118 return this.children;
119 }
120
121 public Element setChildren(List<Element> children) {
122 this.children = children;
123 return this;
124 }
125
126 public final String getContent() {
127 return content;
128 }
129
130 public Element setAttribute(String name, String value) {
131 if (name != null && value != null) {
132 this.attributes.put(name, value);
133 }
134 return this;
135 }
136
137 public Element setAttributes(Hashtable<String, String> attributes) {
138 this.attributes = attributes;
139 return this;
140 }
141
142 public String getAttribute(String name) {
143 if (this.attributes.containsKey(name)) {
144 return this.attributes.get(name);
145 } else {
146 return null;
147 }
148 }
149
150 public Jid getAttributeAsJid(String name) {
151 final String jid = this.getAttribute(name);
152 if (jid != null && !jid.isEmpty()) {
153 try {
154 return Jid.of(jid);
155 } catch (final IllegalArgumentException e) {
156 Log.e(Config.LOGTAG, "could not parse jid " + jid);
157 return null;
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}