Message.java

 1package im.conversations.android.xmpp.model.stanza;
 2
 3import com.google.common.base.Joiner;
 4import com.google.common.base.Strings;
 5import com.google.common.collect.ImmutableMultimap;
 6import com.google.common.collect.Iterables;
 7import com.google.common.collect.Maps;
 8import eu.siacs.conversations.Config;
 9import eu.siacs.conversations.xml.Element;
10import eu.siacs.conversations.xml.LocalizedContent;
11import im.conversations.android.annotation.XmlElement;
12import im.conversations.android.xmpp.model.Extension;
13import im.conversations.android.xmpp.model.jabber.Body;
14import im.conversations.android.xmpp.model.jabber.Subject;
15import java.util.Locale;
16
17@XmlElement
18public class Message extends Stanza {
19
20    public Message() {
21        super(Message.class);
22    }
23
24    public Message(Type type) {
25        this();
26        this.setType(type);
27    }
28
29    public LocalizedContent getBody() {
30        return getLocalizedContent(Body.class);
31    }
32
33    public LocalizedContent getSubject() {
34        return getLocalizedContent(Subject.class);
35    }
36
37    private LocalizedContent getLocalizedContent(final Class<? extends Extension> clazz) {
38        final var builder = new ImmutableMultimap.Builder<String, String>();
39        final var messageLanguage = this.getAttribute("xml:lang");
40        final var parentLanguage =
41                Strings.isNullOrEmpty(messageLanguage)
42                        ? LocalizedContent.STREAM_LANGUAGE
43                        : messageLanguage;
44        for (final var element : this.getExtensions(clazz)) {
45            final var elementLanguage = element.getAttribute("xml:lang");
46            final var language =
47                    Strings.isNullOrEmpty(elementLanguage) ? parentLanguage : elementLanguage;
48            final var content = element.getContent();
49            if (content == null) {
50                continue;
51            }
52            builder.put(language, content);
53        }
54        final var multiMap = builder.build().asMap();
55        if (Config.TREAT_MULTI_CONTENT_AS_INVALID
56                && Iterables.any(multiMap.values(), v -> v.size() > 1)) {
57            return null;
58        }
59        return LocalizedContent.get(Maps.transformValues(multiMap, v -> Joiner.on('\n').join(v)));
60    }
61
62    public Type getType() {
63        final var value = this.getAttribute("type");
64        if (value == null) {
65            return Type.NORMAL;
66        } else {
67            try {
68                return Type.valueOf(value.toUpperCase(Locale.ROOT));
69            } catch (final IllegalArgumentException e) {
70                return null;
71            }
72        }
73    }
74
75    public void setType(final Type type) {
76        if (type == null || type == Type.NORMAL) {
77            this.removeAttribute("type");
78        } else {
79            this.setAttribute("type", type.toString().toLowerCase(Locale.ROOT));
80        }
81    }
82
83    public void setBody(final String text) {
84        this.addExtension(new Body(text));
85    }
86
87    public void setAxolotlMessage(Element axolotlMessage) {
88        this.children.remove(findChild("body"));
89        this.children.add(0, axolotlMessage);
90    }
91
92    public enum Type {
93        ERROR,
94        NORMAL,
95        GROUPCHAT,
96        HEADLINE,
97        CHAT
98    }
99}