001/**
002 *
003 * Copyright 2020 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.smack.c2s.internal;
018
019import java.nio.channels.ClosedChannelException;
020import java.nio.channels.SelectableChannel;
021import java.nio.channels.SelectionKey;
022import java.util.ListIterator;
023import java.util.Queue;
024
025import org.jivesoftware.smack.SmackException;
026import org.jivesoftware.smack.SmackException.NoResponseException;
027import org.jivesoftware.smack.SmackException.NotConnectedException;
028import org.jivesoftware.smack.SmackReactor;
029import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
030import org.jivesoftware.smack.XMPPException;
031import org.jivesoftware.smack.XMPPException.FailedNonzaException;
032import org.jivesoftware.smack.XmppInputOutputFilter;
033import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection;
034import org.jivesoftware.smack.c2s.XmppClientToServerTransport;
035import org.jivesoftware.smack.debugger.SmackDebugger;
036import org.jivesoftware.smack.fsm.ConnectionStateEvent;
037import org.jivesoftware.smack.internal.SmackTlsContext;
038import org.jivesoftware.smack.packet.Nonza;
039import org.jivesoftware.smack.packet.TopLevelStreamElement;
040import org.jivesoftware.smack.packet.XmlEnvironment;
041import org.jivesoftware.smack.util.Consumer;
042import org.jivesoftware.smack.util.Supplier;
043import org.jivesoftware.smack.xml.XmlPullParser;
044
045public abstract class ModularXmppClientToServerConnectionInternal {
046
047    private final SmackReactor reactor;
048
049    public final ModularXmppClientToServerConnection connection;
050
051    public final SmackDebugger smackDebugger;
052
053    public final Queue<TopLevelStreamElement> outgoingElementsQueue;
054
055    public ModularXmppClientToServerConnectionInternal(ModularXmppClientToServerConnection connection, SmackReactor reactor,
056                    SmackDebugger smackDebugger, Queue<TopLevelStreamElement> outgoingElementsQueue) {
057        this.connection = connection;
058        this.reactor = reactor;
059        this.smackDebugger = smackDebugger;
060        this.outgoingElementsQueue = outgoingElementsQueue;
061    }
062
063    public SelectionKey registerWithSelector(SelectableChannel channel, int ops, ChannelSelectedCallback callback)
064                    throws ClosedChannelException {
065        return reactor.registerWithSelector(channel, ops, callback);
066    }
067
068    public void setInterestOps(SelectionKey selectionKey, int interestOps) {
069        reactor.setInterestOps(selectionKey, interestOps);
070    }
071
072    public final void withSmackDebugger(Consumer<SmackDebugger> smackDebuggerConsumer) {
073        if (smackDebugger == null) {
074            return;
075        }
076
077        smackDebuggerConsumer.accept(smackDebugger);
078    }
079
080    public abstract XmlEnvironment getOutgoingStreamXmlEnvironment();
081
082    // TODO: The incomingElement parameter was previously of type TopLevelStreamElement, but I believe it has to be
083    // of type string. But would this also work for BOSH or WebSocket?
084    public abstract void parseAndProcessElement(String wrappedCompleteIncomingElement);
085
086    public abstract void notifyConnectionError(Exception e);
087
088    public abstract void onStreamOpen(XmlPullParser parser);
089
090    public abstract void onStreamClosed();
091
092    public abstract void fireFirstLevelElementSendListeners(TopLevelStreamElement element);
093
094    public abstract void invokeConnectionStateMachineListener(ConnectionStateEvent connectionStateEvent);
095
096    public abstract void addXmppInputOutputFilter(XmppInputOutputFilter xmppInputOutputFilter);
097
098    public abstract ListIterator<XmppInputOutputFilter> getXmppInputOutputFilterBeginIterator();
099
100    public abstract ListIterator<XmppInputOutputFilter> getXmppInputOutputFilterEndIterator();
101
102    public abstract void newStreamOpenWaitForFeaturesSequence(String waitFor) throws InterruptedException,
103                    NoResponseException, NotConnectedException, SmackException, XMPPException;
104
105    public abstract SmackTlsContext getSmackTlsContext();
106
107    public abstract <SN extends Nonza, FN extends Nonza> SN sendAndWaitForResponse(Nonza nonza,
108                    Class<SN> successNonzaClass, Class<FN> failedNonzaClass)
109                    throws NoResponseException, NotConnectedException, FailedNonzaException, InterruptedException;
110
111    public abstract void asyncGo(Runnable runnable);
112
113    public abstract void waitForConditionOrThrowConnectionException(Supplier<Boolean> condition, String waitFor) throws InterruptedException, SmackException, XMPPException;
114
115    public abstract void notifyWaitingThreads();
116
117    public abstract void setCompressionEnabled(boolean compressionEnabled);
118
119    /**
120     * Set the active transport (TCP, BOSH, WebSocket, …) to be used for the XMPP connection. Also marks the connection
121     * as connected.
122     *
123     * @param xmppTransport the active transport.
124     */
125    public abstract void setTransport(XmppClientToServerTransport xmppTransport);
126}