Element.java

  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	private String findInternationalizedChildContent(String name, @NonNull String language) {
 79		final 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		final String value = contents.get(null);
 94		if (value != null) {
 95			return value;
 96		}
 97		final String[] values = contents.values().toArray(new String[0]);
 98		return values.length == 0 ? null : values[0];
 99	}
100
101	public Element findChild(String name, String xmlns) {
102		for (Element child : this.children) {
103			if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
104				return child;
105			}
106		}
107		return null;
108	}
109
110	public String findChildContent(String name, String xmlns) {
111		Element element = findChild(name,xmlns);
112		return element == null ? null : element.getContent();
113	}
114
115	public boolean hasChild(final String name) {
116		return findChild(name) != null;
117	}
118
119	public boolean hasChild(final String name, final String xmlns) {
120		return findChild(name, xmlns) != null;
121	}
122
123	public List<Element> getChildren() {
124		return this.children;
125	}
126
127	public Element setChildren(List<Element> children) {
128		this.children = children;
129		return this;
130	}
131
132	public final String getContent() {
133		return content;
134	}
135
136	public Element setAttribute(String name, String value) {
137		if (name != null && value != null) {
138			this.attributes.put(name, value);
139		}
140		return this;
141	}
142
143	public Element removeAttribute(String name) {
144		this.attributes.remove(name);
145		return this;
146	}
147
148	public Element setAttributes(Hashtable<String, String> attributes) {
149		this.attributes = attributes;
150		return this;
151	}
152
153	public String getAttribute(String name) {
154		if (this.attributes.containsKey(name)) {
155			return this.attributes.get(name);
156		} else {
157			return null;
158		}
159	}
160
161	public Jid getAttributeAsJid(String name) {
162		final String jid = this.getAttribute(name);
163		if (jid != null && !jid.isEmpty()) {
164			try {
165				return Jid.ofEscaped(jid);
166			} catch (final IllegalArgumentException e) {
167				return InvalidJid.of(jid, this instanceof MessagePacket);
168			}
169		}
170		return null;
171	}
172
173	public Hashtable<String, String> getAttributes() {
174		return this.attributes;
175	}
176
177	public String toString() {
178		StringBuilder elementOutput = new StringBuilder();
179		if ((content == null) && (children.size() == 0)) {
180			Tag emptyTag = Tag.empty(name);
181			emptyTag.setAtttributes(this.attributes);
182			elementOutput.append(emptyTag.toString());
183		} else {
184			Tag startTag = Tag.start(name);
185			startTag.setAtttributes(this.attributes);
186			elementOutput.append(startTag);
187			if (content != null) {
188				elementOutput.append(XmlHelper.encodeEntities(content));
189			} else {
190				for (Element child : children) {
191					elementOutput.append(child.toString());
192				}
193			}
194			Tag endTag = Tag.end(name);
195			elementOutput.append(endTag);
196		}
197		return elementOutput.toString();
198	}
199
200	public final String getName() {
201		return name;
202	}
203
204	public void clearChildren() {
205		this.children.clear();
206	}
207
208	public void setAttribute(String name, long value) {
209		this.setAttribute(name, Long.toString(value));
210	}
211
212	public void setAttribute(String name, int value) {
213		this.setAttribute(name, Integer.toString(value));
214	}
215
216	public boolean getAttributeAsBoolean(String name) {
217		String attr = getAttribute(name);
218		return (attr != null && (attr.equalsIgnoreCase("true") || attr.equalsIgnoreCase("1")));
219	}
220
221	public String getNamespace() {
222		return getAttribute("xmlns");
223	}
224}