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.smackx.jingle.element.Jingle;
027import org.jivesoftware.smackx.jingle.element.JingleContent;
028import org.jivesoftware.smackx.jingle.transports.JingleTransportSession;
029
030import org.jxmpp.jid.FullJid;
031
032public abstract class JingleSession implements JingleSessionHandler {
033    protected HashSet<String> failedTransportMethods = new HashSet<>();
034
035    protected final FullJid local;
036
037    protected final FullJid remote;
038
039    protected final Role role;
040
041    protected final String sid;
042
043    protected final List<JingleContent> contents = new ArrayList<>();
044
045    protected ArrayList<Future<?>> queued = new ArrayList<>();
046    protected JingleTransportSession<?> transportSession;
047
048    public JingleSession(FullJid initiator, FullJid responder, Role role, String sid) {
049        this(initiator, responder, role, sid, null);
050    }
051
052    public JingleSession(FullJid initiator, FullJid responder, Role role, String sid, List<JingleContent> contents) {
053        if (role == Role.initiator) {
054            this.local = initiator;
055            this.remote = responder;
056        } else {
057            this.local = responder;
058            this.remote = initiator;
059        }
060        this.sid = sid;
061        this.role = role;
062
063        if (contents != null) {
064            this.contents.addAll(contents);
065        }
066    }
067
068    public FullJid getInitiator() {
069        return isInitiator() ? local : remote;
070    }
071
072    public boolean isInitiator() {
073        return role == Role.initiator;
074    }
075
076    public FullJid getResponder() {
077        return isResponder() ? local : remote;
078    }
079
080    public boolean isResponder() {
081        return role == Role.responder;
082    }
083
084    public FullJid getRemote() {
085        return remote;
086    }
087
088    public FullJid getLocal() {
089        return local;
090    }
091
092    public String getSessionId() {
093        return sid;
094    }
095
096    public FullJidAndSessionId getFullJidAndSessionId() {
097        return new FullJidAndSessionId(remote, sid);
098    }
099
100    public List<JingleContent> getContents() {
101        return contents;
102    }
103
104    public JingleTransportSession<?> getTransportSession() {
105        return transportSession;
106    }
107
108    protected void setTransportSession(JingleTransportSession<?> transportSession) {
109        this.transportSession = transportSession;
110    }
111
112    @Override
113    public int hashCode() {
114        int hashCode = 31 + getInitiator().hashCode();
115        hashCode = 31 * hashCode + getResponder().hashCode();
116        hashCode = 31 * hashCode + getSessionId().hashCode();
117        return hashCode;
118    }
119
120    @Override
121    public boolean equals(Object other) {
122        if (!(other instanceof JingleSession)) {
123            return false;
124        }
125
126        JingleSession otherJingleSession = (JingleSession) other;
127        return getInitiator().equals(otherJingleSession.getInitiator())
128                && getResponder().equals(otherJingleSession.getResponder())
129                && sid.equals(otherJingleSession.sid);
130    }
131
132    @Override
133    public IQ handleJingleSessionRequest(Jingle jingle) {
134        switch (jingle.getAction()) {
135        case content_accept:
136            return handleContentAccept(jingle);
137        case content_add:
138            return handleContentAdd(jingle);
139        case content_modify:
140            return handleContentModify(jingle);
141        case content_reject:
142            return handleContentReject(jingle);
143        case content_remove:
144            return handleContentRemove(jingle);
145        case description_info:
146            return handleDescriptionInfo(jingle);
147        case session_info:
148            return handleSessionInfo(jingle);
149        case security_info:
150            return handleSecurityInfo(jingle);
151        case session_accept:
152            return handleSessionAccept(jingle);
153        case transport_accept:
154            return handleTransportAccept(jingle);
155        case transport_info:
156            return transportSession.handleTransportInfo(jingle);
157        case session_initiate:
158            return handleSessionInitiate(jingle);
159        case transport_reject:
160            return handleTransportReject(jingle);
161        case session_terminate:
162            return handleSessionTerminate(jingle);
163        case transport_replace:
164            return handleTransportReplace(jingle);
165        default:
166            return IQ.createResultIQ(jingle);
167        }
168    }
169
170    protected IQ handleSessionInitiate(Jingle sessionInitiate) {
171        return IQ.createResultIQ(sessionInitiate);
172    }
173
174    protected IQ handleSessionTerminate(Jingle sessionTerminate) {
175        return IQ.createResultIQ(sessionTerminate);
176    }
177
178    protected IQ handleSessionInfo(Jingle sessionInfo) {
179        return IQ.createResultIQ(sessionInfo);
180    }
181
182    protected IQ handleSessionAccept(Jingle sessionAccept) {
183        return IQ.createResultIQ(sessionAccept);
184    }
185
186    protected IQ handleContentAdd(Jingle contentAdd) {
187        return IQ.createResultIQ(contentAdd);
188    }
189
190    protected IQ handleContentAccept(Jingle contentAccept) {
191        return IQ.createResultIQ(contentAccept);
192    }
193
194    protected IQ handleContentModify(Jingle contentModify) {
195        return IQ.createResultIQ(contentModify);
196    }
197
198    protected IQ handleContentReject(Jingle contentReject) {
199        return IQ.createResultIQ(contentReject);
200    }
201
202    protected IQ handleContentRemove(Jingle contentRemove) {
203        return IQ.createResultIQ(contentRemove);
204    }
205
206    protected IQ handleDescriptionInfo(Jingle descriptionInfo) {
207        return IQ.createResultIQ(descriptionInfo);
208    }
209
210    protected IQ handleSecurityInfo(Jingle securityInfo) {
211        return IQ.createResultIQ(securityInfo);
212    }
213
214    protected IQ handleTransportAccept(Jingle transportAccept) {
215        return IQ.createResultIQ(transportAccept);
216    }
217
218    protected IQ handleTransportReplace(Jingle transportReplace) {
219        return IQ.createResultIQ(transportReplace);
220    }
221
222    protected IQ handleTransportReject(Jingle transportReject) {
223        return IQ.createResultIQ(transportReject);
224    }
225
226    public abstract XMPPConnection getConnection();
227
228    public abstract void onTransportMethodFailed(String namespace);
229
230}