001/**
002 *
003 * Copyright 2017 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.jingle;
018
019import java.util.ArrayList;
020import java.util.HashSet;
021import java.util.List;
022import java.util.concurrent.Future;
023
024import org.jivesoftware.smack.XMPPConnection;
025import org.jivesoftware.smack.packet.IQ;
026import org.jivesoftware.smack.util.EqualsUtil;
027import org.jivesoftware.smack.util.HashCode;
028
029import org.jivesoftware.smackx.jingle.element.Jingle;
030import org.jivesoftware.smackx.jingle.element.JingleContent;
031import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
032
033import org.jxmpp.jid.FullJid;
034
035public abstract class JingleSession implements JingleSessionHandler {
036    protected HashSet<String> failedTransportMethods = new HashSet<>();
037
038    protected final FullJid local;
039
040    protected final FullJid remote;
041
042    protected final Role role;
043
044    protected final String sid;
045
046    protected final List<JingleContent> contents = new ArrayList<>();
047
048    protected ArrayList<Future<?>> queued = new ArrayList<>();
049    protected JingleTransportSession<?> transportSession;
050
051    public JingleSession(FullJid initiator, FullJid responder, Role role, String sid) {
052        this(initiator, responder, role, sid, null);
053    }
054
055    public JingleSession(FullJid initiator, FullJid responder, Role role, String sid, List<JingleContent> contents) {
056        if (role == Role.initiator) {
057            this.local = initiator;
058            this.remote = responder;
059        } else {
060            this.local = responder;
061            this.remote = initiator;
062        }
063        this.sid = sid;
064        this.role = role;
065
066        if (contents != null) {
067            this.contents.addAll(contents);
068        }
069    }
070
071    public FullJid getInitiator() {
072        return isInitiator() ? local : remote;
073    }
074
075    public boolean isInitiator() {
076        return role == Role.initiator;
077    }
078
079    public FullJid getResponder() {
080        return isResponder() ? local : remote;
081    }
082
083    public boolean isResponder() {
084        return role == Role.responder;
085    }
086
087    public FullJid getRemote() {
088        return remote;
089    }
090
091    public FullJid getLocal() {
092        return local;
093    }
094
095    public String getSessionId() {
096        return sid;
097    }
098
099    public FullJidAndSessionId getFullJidAndSessionId() {
100        return new FullJidAndSessionId(remote, sid);
101    }
102
103    public List<JingleContent> getContents() {
104        return contents;
105    }
106
107    public JingleTransportSession<?> getTransportSession() {
108        return transportSession;
109    }
110
111    protected void setTransportSession(JingleTransportSession<?> transportSession) {
112        this.transportSession = transportSession;
113    }
114
115    @Override
116    public int hashCode() {
117        return HashCode.builder()
118                       .append(getInitiator())
119                       .append(getResponder())
120                       .append(getSessionId())
121                       .build();
122    }
123
124    @Override
125    public boolean equals(Object other) {
126        return EqualsUtil.equals(this, other, (e, o) ->
127            e.append(getInitiator(), o.getInitiator())
128              .append(getResponder(), o.getResponder())
129              .append(sid, o.sid)
130        );
131    }
132
133    @Override
134    public IQ handleJingleSessionRequest(Jingle jingle) {
135        switch (jingle.getAction()) {
136        case content_accept:
137            return handleContentAccept(jingle);
138        case content_add:
139            return handleContentAdd(jingle);
140        case content_modify:
141            return handleContentModify(jingle);
142        case content_reject:
143            return handleContentReject(jingle);
144        case content_remove:
145            return handleContentRemove(jingle);
146        case description_info:
147            return handleDescriptionInfo(jingle);
148        case session_info:
149            return handleSessionInfo(jingle);
150        case security_info:
151            return handleSecurityInfo(jingle);
152        case session_accept:
153            return handleSessionAccept(jingle);
154        case transport_accept:
155            return handleTransportAccept(jingle);
156        case transport_info:
157            return transportSession.handleTransportInfo(jingle);
158        case session_initiate:
159            return handleSessionInitiate(jingle);
160        case transport_reject:
161            return handleTransportReject(jingle);
162        case session_terminate:
163            return handleSessionTerminate(jingle);
164        case transport_replace:
165            return handleTransportReplace(jingle);
166        default:
167            return IQ.createResultIQ(jingle);
168        }
169    }
170
171    protected IQ handleSessionInitiate(Jingle sessionInitiate) {
172        return IQ.createResultIQ(sessionInitiate);
173    }
174
175    protected IQ handleSessionTerminate(Jingle sessionTerminate) {
176        return IQ.createResultIQ(sessionTerminate);
177    }
178
179    protected IQ handleSessionInfo(Jingle sessionInfo) {
180        return IQ.createResultIQ(sessionInfo);
181    }
182
183    protected IQ handleSessionAccept(Jingle sessionAccept) {
184        return IQ.createResultIQ(sessionAccept);
185    }
186
187    protected IQ handleContentAdd(Jingle contentAdd) {
188        return IQ.createResultIQ(contentAdd);
189    }
190
191    protected IQ handleContentAccept(Jingle contentAccept) {
192        return IQ.createResultIQ(contentAccept);
193    }
194
195    protected IQ handleContentModify(Jingle contentModify) {
196        return IQ.createResultIQ(contentModify);
197    }
198
199    protected IQ handleContentReject(Jingle contentReject) {
200        return IQ.createResultIQ(contentReject);
201    }
202
203    protected IQ handleContentRemove(Jingle contentRemove) {
204        return IQ.createResultIQ(contentRemove);
205    }
206
207    protected IQ handleDescriptionInfo(Jingle descriptionInfo) {
208        return IQ.createResultIQ(descriptionInfo);
209    }
210
211    protected IQ handleSecurityInfo(Jingle securityInfo) {
212        return IQ.createResultIQ(securityInfo);
213    }
214
215    protected IQ handleTransportAccept(Jingle transportAccept) {
216        return IQ.createResultIQ(transportAccept);
217    }
218
219    protected IQ handleTransportReplace(Jingle transportReplace) {
220        return IQ.createResultIQ(transportReplace);
221    }
222
223    protected IQ handleTransportReject(Jingle transportReject) {
224        return IQ.createResultIQ(transportReject);
225    }
226
227    public abstract XMPPConnection getConnection();
228
229    public abstract void onTransportMethodFailed(String namespace);
230
231}