Element.java

  1package eu.siacs.conversations.xml;
  2
  3import com.google.common.base.Optional;
  4import com.google.common.primitives.Ints;
  5
  6import org.jetbrains.annotations.NotNull;
  7
  8import java.util.ArrayList;
  9import java.util.Hashtable;
 10import java.util.List;
 11
 12import eu.siacs.conversations.utils.XmlHelper;
 13import eu.siacs.conversations.xmpp.InvalidJid;
 14import eu.siacs.conversations.xmpp.Jid;
 15import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 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 LocalizedContent findInternationalizedChildContentInDefaultNamespace(String name) {
 74        return LocalizedContent.get(this, name);
 75    }
 76
 77    public Element findChild(String name, String xmlns) {
 78        for (Element child : this.children) {
 79            if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
 80                return child;
 81            }
 82        }
 83        return null;
 84    }
 85
 86    public Element findChildEnsureSingle(String name, String xmlns) {
 87        final List<Element> results = new ArrayList<>();
 88        for (Element child : this.children) {
 89            if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
 90                results.add(child);
 91            }
 92        }
 93        if (results.size() == 1) {
 94            return results.get(0);
 95        }
 96        return null;
 97    }
 98
 99    public String findChildContent(String name, String xmlns) {
100        Element element = findChild(name, xmlns);
101        return element == null ? null : element.getContent();
102    }
103
104    public boolean hasChild(final String name) {
105        return findChild(name) != null;
106    }
107
108    public boolean hasChild(final String name, final String xmlns) {
109        return findChild(name, xmlns) != null;
110    }
111
112    public List<Element> getChildren() {
113        return this.children;
114    }
115
116    public Element setChildren(List<Element> children) {
117        this.children = children;
118        return this;
119    }
120
121    public final String getContent() {
122        return content;
123    }
124
125    public Element setAttribute(String name, String value) {
126        if (name != null && value != null) {
127            this.attributes.put(name, value);
128        }
129        return this;
130    }
131
132    public Element setAttribute(String name, Jid value) {
133        if (name != null && value != null) {
134            this.attributes.put(name, value.toEscapedString());
135        }
136        return this;
137    }
138
139    public void removeAttribute(final String name) {
140        this.attributes.remove(name);
141    }
142
143    public Element setAttributes(Hashtable<String, String> attributes) {
144        this.attributes = attributes;
145        return this;
146    }
147
148    public String getAttribute(String name) {
149        if (this.attributes.containsKey(name)) {
150            return this.attributes.get(name);
151        } else {
152            return null;
153        }
154    }
155
156    public Optional<Integer> getOptionalIntAttribute(final String name) {
157        final String value = getAttribute(name);
158        if (value == null) {
159            return Optional.absent();
160        }
161        return Optional.fromNullable(Ints.tryParse(value));
162    }
163
164    public Jid getAttributeAsJid(String name) {
165        final String jid = this.getAttribute(name);
166        if (jid != null && !jid.isEmpty()) {
167            try {
168                return Jid.ofEscaped(jid);
169            } catch (final IllegalArgumentException e) {
170                return InvalidJid.of(jid, this instanceof MessagePacket);
171            }
172        }
173        return null;
174    }
175
176    public Hashtable<String, String> getAttributes() {
177        return this.attributes;
178    }
179
180    @NotNull
181    public String toString() {
182        final StringBuilder elementOutput = new StringBuilder();
183        if ((content == null) && (children.size() == 0)) {
184            final Tag emptyTag = Tag.empty(name);
185            emptyTag.setAttributes(this.attributes);
186            elementOutput.append(emptyTag);
187        } else {
188            final Tag startTag = Tag.start(name);
189            startTag.setAttributes(this.attributes);
190            elementOutput.append(startTag);
191            if (content != null) {
192                elementOutput.append(XmlHelper.encodeEntities(content));
193            } else {
194                for (final Element child : children) {
195                    elementOutput.append(child.toString());
196                }
197            }
198            final Tag endTag = Tag.end(name);
199            elementOutput.append(endTag);
200        }
201        return elementOutput.toString();
202    }
203
204    public final String getName() {
205        return name;
206    }
207
208    public void clearChildren() {
209        this.children.clear();
210    }
211
212    public void setAttribute(String name, long value) {
213        this.setAttribute(name, Long.toString(value));
214    }
215
216    public void setAttribute(String name, int value) {
217        this.setAttribute(name, Integer.toString(value));
218    }
219
220    public boolean getAttributeAsBoolean(String name) {
221        String attr = getAttribute(name);
222        return (attr != null && (attr.equalsIgnoreCase("true") || attr.equalsIgnoreCase("1")));
223    }
224
225    public String getNamespace() {
226        return getAttribute("xmlns");
227    }
228}