JinglePacket.java

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