Jingle.java

  1package im.conversations.android.xmpp.model.jingle;
  2
  3import androidx.annotation.NonNull;
  4
  5import com.google.common.base.CaseFormat;
  6import com.google.common.base.Preconditions;
  7import com.google.common.base.Strings;
  8import com.google.common.collect.ImmutableMap;
  9
 10import eu.siacs.conversations.xml.Element;
 11import eu.siacs.conversations.xml.Namespace;
 12import eu.siacs.conversations.xmpp.Jid;
 13import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
 14import eu.siacs.conversations.xmpp.jingle.stanzas.Group;
 15import eu.siacs.conversations.xmpp.jingle.stanzas.Reason;
 16
 17import im.conversations.android.annotation.XmlElement;
 18import im.conversations.android.xmpp.model.Extension;
 19
 20import java.util.Map;
 21
 22@XmlElement
 23public class Jingle extends Extension {
 24
 25    public Jingle() {
 26        super(Jingle.class);
 27    }
 28
 29    public Jingle(final Action action, final String sessionId) {
 30        this();
 31        this.setAttribute("sid", sessionId);
 32        this.setAttribute("action", action.toString());
 33    }
 34
 35    public String getSessionId() {
 36        return this.getAttribute("sid");
 37    }
 38
 39    public Action getAction() {
 40        return Action.of(this.getAttribute("action"));
 41    }
 42
 43    public ReasonWrapper getReason() {
 44        final Element reasonElement = this.findChild("reason");
 45        if (reasonElement == null) {
 46            return new ReasonWrapper(Reason.UNKNOWN, null);
 47        }
 48        String text = null;
 49        Reason reason = Reason.UNKNOWN;
 50        for (Element child : reasonElement.getChildren()) {
 51            if ("text".equals(child.getName())) {
 52                text = child.getContent();
 53            } else {
 54                reason = Reason.of(child.getName());
 55            }
 56        }
 57        return new ReasonWrapper(reason, text);
 58    }
 59
 60    public void setReason(final Reason reason, final String text) {
 61        final Element reasonElement = this.addChild("reason");
 62        reasonElement.addChild(reason.toString());
 63        if (!Strings.isNullOrEmpty(text)) {
 64            reasonElement.addChild("text").setContent(text);
 65        }
 66    }
 67
 68    // RECOMMENDED for session-initiate, NOT RECOMMENDED otherwise
 69    public void setInitiator(final Jid initiator) {
 70        Preconditions.checkArgument(initiator.isFullJid(), "initiator should be a full JID");
 71        this.setAttribute("initiator", initiator);
 72    }
 73
 74    // RECOMMENDED for session-accept, NOT RECOMMENDED otherwise
 75    public void setResponder(final Jid responder) {
 76        Preconditions.checkArgument(responder.isFullJid(), "responder should be a full JID");
 77        this.setAttribute("responder", responder);
 78    }
 79
 80    public Group getGroup() {
 81        final Element group = this.findChild("group", Namespace.JINGLE_APPS_GROUPING);
 82        return group == null ? null : Group.upgrade(group);
 83    }
 84
 85    public void addGroup(final Group group) {
 86        this.addChild(group);
 87    }
 88
 89    // TODO deprecate this somehow and make file transfer fail if there are multiple (or something)
 90    public Content getJingleContent() {
 91        final Element content = this.findChild("content");
 92        return content == null ? null : Content.upgrade(content);
 93    }
 94
 95    public void addJingleContent(final Content content) { // take content interface
 96        this.addChild(content);
 97    }
 98
 99
100    public Map<String, Content> getJingleContents() {
101        ImmutableMap.Builder<String, Content> builder = new ImmutableMap.Builder<>();
102        for (final Element child : this.getChildren()) {
103            if ("content".equals(child.getName())) {
104                final Content content = Content.upgrade(child);
105                builder.put(content.getContentName(), content);
106            }
107        }
108        return builder.build();
109    }
110
111    public enum Action {
112        CONTENT_ACCEPT,
113        CONTENT_ADD,
114        CONTENT_MODIFY,
115        CONTENT_REJECT,
116        CONTENT_REMOVE,
117        DESCRIPTION_INFO,
118        SECURITY_INFO,
119        SESSION_ACCEPT,
120        SESSION_INFO,
121        SESSION_INITIATE,
122        SESSION_TERMINATE,
123        TRANSPORT_ACCEPT,
124        TRANSPORT_INFO,
125        TRANSPORT_REJECT,
126        TRANSPORT_REPLACE;
127
128        public static Action of(final String value) {
129            if (Strings.isNullOrEmpty(value)) {
130                return null;
131            }
132            try {
133                return Action.valueOf(
134                        CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, value));
135            } catch (final IllegalArgumentException e) {
136                return null;
137            }
138        }
139
140        @Override
141        @NonNull
142        public String toString() {
143            return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, super.toString());
144        }
145    }
146
147    public static class ReasonWrapper {
148        public final Reason reason;
149        public final String text;
150
151        public ReasonWrapper(Reason reason, String text) {
152            this.reason = reason;
153            this.text = text;
154        }
155    }
156}