Introduce Smack's Modular Connection Architecture
This is a complete redesign of what was previously XmppNioTcpConnection. The new architecture allows to extend an XMPP client to server (c2s) connection with new transport bindings and other extensions.mix
parent
cec312fe64
commit
cc636fff21
@ -0,0 +1,35 @@
|
||||
Smack's Modular Connection Architecture
|
||||
======================================
|
||||
|
||||
[Back](index.md)
|
||||
|
||||
**Note: Everything related to the modular connection architecture is currently considered experimental and should not be used in production. Use the mature `XMPPTCPConnection` if you do not feel adventurous.
|
||||
|
||||
Smack's modular connection architecture allows to extend a XMPP c2s (client-to-server) connection with additional functionalty by adding modules.
|
||||
Those modules extend the Finite State Machine (FSM) within the `ModularXmppClientToServerConnection` with new states.
|
||||
|
||||
Connection modules can either be
|
||||
- Transports
|
||||
- Extensions
|
||||
|
||||
Transports bind the XMPP XML stream to an underlying transport like TCP, WebSockets, BOSH, and allow for the different particularities of transports like DirectTLS ([XEP-0368](https://xmpp.org/extensions/xep-0368.html)).
|
||||
This eventually means that a single transport module can implement multiple transport mechanisms.
|
||||
For example the TCP transport module implements the RFC6120 TCP and the XEP-0368 direct TLS TCP transport bindings.
|
||||
|
||||
Extensions allow for a richer functionality of the connection. Those include
|
||||
- Compression
|
||||
- zlib ([XEP-0138](https://xmpp.org/extensions/xep-0138.html))
|
||||
- [Efficient XML Interchange (EXI)](https://www.w3.org/TR/exi/)
|
||||
- Instant Stream Resumption ([XEP-0397](https://xmpp.org/extensions/xep-0397.html)
|
||||
- Bind2
|
||||
- Stream Management
|
||||
|
||||
Note that not all extensions work with every transport.
|
||||
For example compression only works with TCP-based transport bindings.
|
||||
|
||||
|
||||
Connection modules are plugged into the the modular connection via their constructor. and they usually declare backwards edges to some common, generic connection state of the FSM.
|
||||
|
||||
Modules and states always have an accompanying *descriptor* type.
|
||||
`ModuleDescriptor` and `StateDescriptor` exist without an connection instance.
|
||||
They describe the module and state metadata, while their modules are states are instanciated once a modular connection is instanciated.
|
@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2018 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
||||
import org.jivesoftware.smack.SmackReactor.ChannelSelectedCallback;
|
||||
import org.jivesoftware.smack.fsm.AbstractXmppStateMachineConnection;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptor;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptorGraph.GraphVertex;
|
||||
|
||||
public abstract class AbstractXmppNioConnection extends AbstractXmppStateMachineConnection {
|
||||
|
||||
protected AbstractXmppNioConnection(ConnectionConfiguration configuration, GraphVertex<StateDescriptor> initialStateDescriptorVertex) {
|
||||
super(configuration, initialStateDescriptorVertex);
|
||||
}
|
||||
|
||||
protected SelectionKey registerWithSelector(SelectableChannel channel, int ops, ChannelSelectedCallback callback)
|
||||
throws ClosedChannelException {
|
||||
return SMACK_REACTOR.registerWithSelector(channel, ops, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the interest Ops of a SelectionKey. Since Java's NIO interestOps(int) can block at any time, we use a queue
|
||||
* to perform the actual operation in the reactor where we can perform this operation non-blocking.
|
||||
*
|
||||
* @param selectionKey TODO javadoc me please
|
||||
* @param interestOps TODO javadoc me please
|
||||
*/
|
||||
protected void setInterestOps(SelectionKey selectionKey, int interestOps) {
|
||||
SMACK_REACTOR.setInterestOps(selectionKey, interestOps);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2019-2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.bind2;
|
||||
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.AuthenticatedAndResourceBoundStateDescriptor;
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.ConnectedButUnauthenticatedStateDescriptor;
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection.SaslAuthenticationStateDescriptor;
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionModule;
|
||||
import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
|
||||
import org.jivesoftware.smack.c2s.internal.WalkStateGraphContext;
|
||||
import org.jivesoftware.smack.fsm.State;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptor;
|
||||
import org.jivesoftware.smack.fsm.StateTransitionResult;
|
||||
|
||||
public class Bind2Module extends ModularXmppClientToServerConnectionModule<Bind2ModuleDescriptor> {
|
||||
|
||||
protected Bind2Module(Bind2ModuleDescriptor moduleDescriptor,
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
super(moduleDescriptor, connectionInternal);
|
||||
}
|
||||
|
||||
public static final class Bind2StateDescriptor extends StateDescriptor {
|
||||
private Bind2StateDescriptor() {
|
||||
super(Bind2State.class, 386, StateDescriptor.Property.notImplemented);
|
||||
|
||||
addPredeccessor(ConnectedButUnauthenticatedStateDescriptor.class);
|
||||
addSuccessor(AuthenticatedAndResourceBoundStateDescriptor.class);
|
||||
declarePrecedenceOver(SaslAuthenticationStateDescriptor.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bind2Module.Bind2State constructState(ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
// This is the trick: the module is constructed prior the states, so we get the actual state out of the module by fetching the module from the connection.
|
||||
Bind2Module bind2Module = connectionInternal.connection.getConnectionModuleFor(Bind2ModuleDescriptor.class);
|
||||
return bind2Module.constructBind2State(this, connectionInternal);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Bind2State extends State {
|
||||
|
||||
private Bind2State(Bind2StateDescriptor bind2StateDescriptor,
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
super(bind2StateDescriptor, connectionInternal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateTransitionResult.TransitionImpossible isTransitionToPossible(WalkStateGraphContext walkStateGraphContext) {
|
||||
return new StateTransitionResult.TransitionImpossibleBecauseNotImplemented(stateDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateTransitionResult.AttemptResult transitionInto(WalkStateGraphContext walkStateGraphContext) {
|
||||
throw new IllegalStateException("Bind2 not implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Bind2State constructBind2State(Bind2StateDescriptor bind2StateDescriptor,
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
return new Bind2State(bind2StateDescriptor, connectionInternal);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2019-2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.bind2;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionConfiguration;
|
||||
import org.jivesoftware.smack.c2s.ModularXmppClientToServerConnectionModuleDescriptor;
|
||||
import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptor;
|
||||
|
||||
public class Bind2ModuleDescriptor extends ModularXmppClientToServerConnectionModuleDescriptor {
|
||||
|
||||
private static final Bind2ModuleDescriptor INSTANCE = new Bind2ModuleDescriptor();
|
||||
|
||||
@Override
|
||||
protected Set<Class<? extends StateDescriptor>> getStateDescriptors() {
|
||||
return Collections.singleton(Bind2Module.Bind2StateDescriptor.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bind2Module constructXmppConnectionModule(
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
return new Bind2Module(this, connectionInternal);
|
||||
}
|
||||
|
||||
public static class Builder extends ModularXmppClientToServerConnectionModuleDescriptor.Builder {
|
||||
|
||||
protected Builder(ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder) {
|
||||
super(connectionConfigurationBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bind2ModuleDescriptor build() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes and interfaces for Bind 2.0 (XEP-0386).
|
||||
*/
|
||||
package org.jivesoftware.smack.bind2;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,167 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2019-2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.c2s;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptor;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptorGraph;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptorGraph.GraphVertex;
|
||||
import org.jivesoftware.smack.util.CollectionUtil;
|
||||
|
||||
public final class ModularXmppClientToServerConnectionConfiguration extends ConnectionConfiguration {
|
||||
|
||||
final Set<ModularXmppClientToServerConnectionModuleDescriptor> moduleDescriptors;
|
||||
|
||||
final GraphVertex<StateDescriptor> initialStateDescriptorVertex;
|
||||
|
||||
private ModularXmppClientToServerConnectionConfiguration(Builder builder) {
|
||||
super(builder);
|
||||
|
||||
moduleDescriptors = Collections.unmodifiableSet(CollectionUtil.newSetWith(builder.modulesDescriptors.values()));
|
||||
|
||||
Set<Class<? extends StateDescriptor>> backwardEdgeStateDescriptors = new HashSet<>();
|
||||
// Add backward edges from configured connection modules. Note that all state descriptors from module
|
||||
// descriptors are backwards edges.
|
||||
for (ModularXmppClientToServerConnectionModuleDescriptor moduleDescriptor : moduleDescriptors) {
|
||||
Set<Class<? extends StateDescriptor>> moduleStateDescriptors = moduleDescriptor.getStateDescriptors();
|
||||
backwardEdgeStateDescriptors.addAll(moduleStateDescriptors);
|
||||
}
|
||||
|
||||
try {
|
||||
initialStateDescriptorVertex = StateDescriptorGraph.constructStateDescriptorGraph(backwardEdgeStateDescriptors);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
||||
| NoSuchMethodException | SecurityException e) {
|
||||
// TODO: Depending on the exact exception thrown, this potentially indicates an invalid connection
|
||||
// configuration, e.g. there is no edge from disconnected to connected.
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void printStateGraphInDotFormat(PrintWriter pw, boolean breakStateName) {
|
||||
StateDescriptorGraph.stateDescriptorGraphToDot(Collections.singleton(initialStateDescriptorVertex), pw,
|
||||
breakStateName);
|
||||
}
|
||||
|
||||
public String getStateGraphInDotFormat() {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
|
||||
printStateGraphInDotFormat(pw, true);
|
||||
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static final class Builder
|
||||
extends ConnectionConfiguration.Builder<Builder, ModularXmppClientToServerConnectionConfiguration> {
|
||||
|
||||
private final Map<Class<? extends ModularXmppClientToServerConnectionModuleDescriptor>, ModularXmppClientToServerConnectionModuleDescriptor> modulesDescriptors = new HashMap<>();
|
||||
|
||||
private Builder() {
|
||||
SmackConfiguration.addAllKnownModulesTo(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModularXmppClientToServerConnectionConfiguration build() {
|
||||
return new ModularXmppClientToServerConnectionConfiguration(this);
|
||||
}
|
||||
|
||||
void addModule(ModularXmppClientToServerConnectionModuleDescriptor connectionModule) {
|
||||
Class<? extends ModularXmppClientToServerConnectionModuleDescriptor> moduleDescriptorClass = connectionModule.getClass();
|
||||
if (modulesDescriptors.containsKey(moduleDescriptorClass)) {
|
||||
throw new IllegalArgumentException("A connection module for " + moduleDescriptorClass + " is already configured");
|
||||
}
|
||||
modulesDescriptors.put(moduleDescriptorClass, connectionModule);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Builder addModule(Class<? extends ModularXmppClientToServerConnectionModuleDescriptor> moduleClass) {
|
||||
Class<?>[] declaredClasses = moduleClass.getDeclaredClasses();
|
||||
|
||||
Class<? extends ModularXmppClientToServerConnectionModuleDescriptor.Builder> builderClass = null;
|
||||
for (Class<?> declaredClass : declaredClasses) {
|
||||
if (!ModularXmppClientToServerConnectionModuleDescriptor.Builder.class.isAssignableFrom(declaredClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
builderClass = (Class<? extends ModularXmppClientToServerConnectionModuleDescriptor.Builder>) declaredClass;
|
||||
break;
|
||||
}
|
||||
|
||||
if (builderClass == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Found no builder for " + moduleClass + ". Delcared classes: " + Arrays.toString(declaredClasses));
|
||||
}
|
||||
|
||||
return with(builderClass).buildModule();
|
||||
}
|
||||
|
||||
public <B extends ModularXmppClientToServerConnectionModuleDescriptor.Builder> B with(
|
||||
Class<? extends B> moduleDescriptorBuilderClass) {
|
||||
Constructor<? extends B> moduleDescriptorBuilderCosntructor;
|
||||
try {
|
||||
moduleDescriptorBuilderCosntructor = moduleDescriptorBuilderClass.getDeclaredConstructor(
|
||||
ModularXmppClientToServerConnectionConfiguration.Builder.class);
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
moduleDescriptorBuilderCosntructor.setAccessible(true);
|
||||
|
||||
B moduleDescriptorBuilder;
|
||||
try {
|
||||
moduleDescriptorBuilder = moduleDescriptorBuilderCosntructor.newInstance(this);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
||||
return moduleDescriptorBuilder;
|
||||
}
|
||||
|
||||
public Builder removeModule(Class<? extends ModularXmppClientToServerConnectionModuleDescriptor> moduleClass) {
|
||||
modulesDescriptors.remove(moduleClass);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public Builder removeAllModules() {
|
||||
modulesDescriptors.clear();
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder getThis() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.c2s;
|
||||
|
||||
import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
|
||||
|
||||
public abstract class ModularXmppClientToServerConnectionModule<MD extends ModularXmppClientToServerConnectionModuleDescriptor> {
|
||||
|
||||
protected final MD moduleDescriptor;
|
||||
|
||||
protected final ModularXmppClientToServerConnectionInternal connectionInternal;
|
||||
|
||||
protected ModularXmppClientToServerConnectionModule(MD moduleDescriptor,
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
this.moduleDescriptor = moduleDescriptor;
|
||||
this.connectionInternal = connectionInternal;
|
||||
}
|
||||
|
||||
public MD getModuleDescriptor() {
|
||||
return moduleDescriptor;
|
||||
}
|
||||
|
||||
protected XmppClientToServerTransport getTransport() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2019-2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.c2s;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
|
||||
import org.jivesoftware.smack.fsm.StateDescriptor;
|
||||
|
||||
public abstract class ModularXmppClientToServerConnectionModuleDescriptor {
|
||||
|
||||
protected abstract Set<Class<? extends StateDescriptor>> getStateDescriptors();
|
||||
|
||||
protected abstract ModularXmppClientToServerConnectionModule<? extends ModularXmppClientToServerConnectionModuleDescriptor> constructXmppConnectionModule(
|
||||
ModularXmppClientToServerConnectionInternal connectionInternal);
|
||||
|
||||
public abstract static class Builder {
|
||||
private final ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder;
|
||||
|
||||
protected Builder(ModularXmppClientToServerConnectionConfiguration.Builder connectionConfigurationBuilder) {
|
||||
this.connectionConfigurationBuilder = connectionConfigurationBuilder;
|
||||
}
|
||||
|
||||
protected abstract ModularXmppClientToServerConnectionModuleDescriptor build();
|
||||
|
||||
public ModularXmppClientToServerConnectionConfiguration.Builder buildModule() {
|
||||
ModularXmppClientToServerConnectionModuleDescriptor moduleDescriptor = build();
|
||||
connectionConfigurationBuilder.addModule(moduleDescriptor);
|
||||
return connectionConfigurationBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2019-2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.c2s;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.jivesoftware.smack.SmackFuture;
|
||||
import org.jivesoftware.smack.c2s.internal.ModularXmppClientToServerConnectionInternal;
|
||||
|
||||
public abstract class XmppClientToServerTransport {
|
||||
|
||||
protected final ModularXmppClientToServerConnectionInternal connectionInternal;
|
||||
|
||||
protected XmppClientToServerTransport(ModularXmppClientToServerConnectionInternal connectionInternal) {
|
||||
this.connectionInternal = connectionInternal;
|
||||
}
|
||||
|
||||
protected abstract void resetDiscoveredConnectionEndpoints();
|
||||
|
||||
protected abstract List<SmackFuture<LookupConnectionEndpointsResult, Exception>> lookupConnectionEndpoints();
|
||||
|
||||
protected abstract void loadConnectionEndpoints(LookupConnectionEndpointsSuccess lookupConnectionEndpointsSuccess);
|
||||
|
||||
/**
|
||||
* Notify the transport that new outgoing data is available. Usually this method does not need to be called
|
||||
* explicitly, only if the filters are modified so that they potentially produced new data.
|
||||
*/
|
||||
protected abstract void afterFiltersClosed();
|
||||
|
||||
/**
|
||||
* Called by the CloseConnection state.
|
||||
*/
|
||||
protected abstract void disconnect();
|
||||
|
||||
protected abstract void notifyAboutNewOutgoingElements();
|
||||
|
||||
public abstract SSLSession getSslSession();
|
||||
|
||||
public abstract boolean isConnected();
|
||||
|
||||
public boolean isTransportSecured() {
|
||||
return getSslSession() != null;
|
||||
}
|
||||
|
||||
public abstract Stats getStats();
|
||||
|
||||
public abstract static class Stats {
|
||||
}
|
||||
|
||||
protected interface LookupConnectionEndpointsResult {
|
||||
}
|
||||
|
||||
protected interface LookupConnectionEndpointsSuccess extends LookupConnectionEndpointsResult {
|
||||
}
|
||||
|
||||
public interface LookupConnectionEndpointsFailed extends LookupConnectionEndpointsResult {
|
||||
// TODO: Add something like getExceptions() or getConnectionExceptions()?
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2020 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
< |