Browse Source

Reworked the client/spec/config/builder on how features are implemented and called.

rewrite-connect
Eric Kok 7 years ago
parent
commit
bd73271753
  1. 64
      connect/src/main/java/org/transdroid/connect/Configuration.java
  2. 38
      connect/src/main/java/org/transdroid/connect/clients/Client.java
  3. 42
      connect/src/main/java/org/transdroid/connect/clients/ClientDelegate.java
  4. 15
      connect/src/main/java/org/transdroid/connect/clients/ClientSpec.java
  5. 54
      connect/src/main/java/org/transdroid/connect/clients/Feature.java
  6. 22
      connect/src/main/java/org/transdroid/connect/clients/UnsupportedFeatureException.java
  7. 19
      connect/src/main/java/org/transdroid/connect/clients/rtorrent/Rtorrent.java
  8. 5
      connect/src/main/java/org/transdroid/connect/clients/transmission/Transmission.java
  9. 21
      connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentTest.java

64
connect/src/main/java/org/transdroid/connect/Configuration.java

@ -4,22 +4,66 @@ import com.burgstaller.okhttp.digest.Credentials; @@ -4,22 +4,66 @@ import com.burgstaller.okhttp.digest.Credentials;
import org.transdroid.connect.clients.Client;
import org.transdroid.connect.clients.ClientSpec;
import org.transdroid.connect.util.StringUtil;
/**
* Configuration settings to connect to a torrent client.
*/
public final class Configuration {
private final Client client;
private final String baseUrl;
private final String endpoint;
private final Credentials credentials;
private final boolean loggingEnabled;
private String endpoint;
private Credentials credentials;
private boolean loggingEnabled;
public Configuration(Client client, String baseUrl, String endpoint, String user, String password, boolean loggingEnabled) {
public static class Builder {
private final Client client;
private String baseUrl;
private String endpoint;
private Credentials credentials;
private boolean loggingEnabled;
public Builder(Client client) {
this.client = client;
}
public Builder baseUrl(String baseUrl) {
this.baseUrl = baseUrl;
return this;
}
public Builder endpoint(String endpoint) {
this.endpoint = endpoint;
return this;
}
public Builder credentials(String user, String password) {
this.credentials = new Credentials(user, password);
return this;
}
public Builder loggingEnabled(boolean loggingEnabled) {
this.loggingEnabled = loggingEnabled;
return this;
}
public Configuration build() {
Configuration configuration = new Configuration(client, baseUrl);
configuration.endpoint = this.endpoint;
configuration.credentials = this.credentials;
return configuration;
}
}
private Configuration(Client client, String baseUrl) {
this.client = client;
this.baseUrl = baseUrl;
this.endpoint = endpoint;
this.credentials = (!StringUtil.isEmpty(user) && password != null) ? new Credentials(user, password) : null;
this.loggingEnabled = loggingEnabled;
}
public Client client() {
return client;
}
public String baseUrl() {
@ -38,8 +82,8 @@ public final class Configuration { @@ -38,8 +82,8 @@ public final class Configuration {
return credentials;
}
public ClientSpec create() {
return client.create(this);
public ClientSpec createClient() {
return client.createClient(this);
}
}

38
connect/src/main/java/org/transdroid/connect/clients/Client.java

@ -2,29 +2,45 @@ package org.transdroid.connect.clients; @@ -2,29 +2,45 @@ package org.transdroid.connect.clients;
import org.transdroid.connect.Configuration;
import org.transdroid.connect.clients.rtorrent.Rtorrent;
import org.transdroid.connect.clients.transmission.Transmission;
import java.util.Set;
/**
* Support clients enum, allowing you to create instances (given a configuration) and query for feature support.
*/
@SuppressWarnings("unchecked")
public enum Client {
RTORRENT {
RTORRENT(Rtorrent.class) {
@Override
public ClientSpec create(Configuration configuration) {
public Rtorrent create(Configuration configuration) {
return new Rtorrent(configuration);
}
},
TRANSMISSION(Transmission.class) {
@Override
Set<Feature> features() {
return Rtorrent.FEATURES;
public Transmission create(Configuration configuration) {
return new Transmission();
}
};
public abstract ClientSpec create(Configuration configuration);
final Class<?> type;
Client(Class<?> type) {
this.type = type;
}
public final Class<?> type() {
return type;
}
abstract Object create(Configuration configuration);
abstract Set<Feature> features();
public final ClientSpec createClient(Configuration configuration) {
return new ClientDelegate(configuration.client(), create(configuration));
}
public boolean supports(Feature feature) {
return features().contains(feature);
public final boolean supports(Feature feature) {
return feature.type().isAssignableFrom(type);
}
}

42
connect/src/main/java/org/transdroid/connect/clients/ClientDelegate.java

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
package org.transdroid.connect.clients;
import org.transdroid.connect.model.Torrent;
import io.reactivex.Flowable;
/**
* Wraps an actual client implementation by calling through the appropriate method only if it is supported. This allows the final
* {@link ClientSpec} API to expose all methods without forcing the individual implementations to implement unsupported featured with a no-op.
*/
final class ClientDelegate implements ClientSpec {
private final Client client;
private final Object actual;
ClientDelegate(Client client, Object actual) {
this.client = client;
this.actual = actual;
}
@Override
public Flowable<Torrent> torrents() {
if (client.supports(Feature.LISTING))
return ((Feature.Listing) actual).torrents();
throw new UnsupportedFeatureException(client, Feature.LISTING);
}
@Override
public Flowable<String> clientVersion() {
if (client.supports(Feature.VERSION))
return ((Feature.Version) actual).clientVersion();
throw new UnsupportedFeatureException(client, Feature.VERSION);
}
@Override
public Flowable<Torrent> forceStartTorrent() {
if (client.supports(Feature.FORCE_STARTING))
return ((Feature.ForceStarting) actual).forceStartTorrent();
throw new UnsupportedFeatureException(client, Feature.FORCE_STARTING);
}
}

15
connect/src/main/java/org/transdroid/connect/clients/ClientSpec.java

@ -1,13 +1,10 @@ @@ -1,13 +1,10 @@
package org.transdroid.connect.clients;
import org.transdroid.connect.model.Torrent;
import io.reactivex.Flowable;
public interface ClientSpec {
Flowable<String> clientVersion();
Flowable<Torrent> torrents();
public interface ClientSpec extends
Feature.Version,
Feature.Listing,
Feature.StartingStopping,
Feature.ResumingPausing,
Feature.ForceStarting {
}

54
connect/src/main/java/org/transdroid/connect/clients/Feature.java

@ -1,11 +1,55 @@ @@ -1,11 +1,55 @@
package org.transdroid.connect.clients;
import org.transdroid.connect.model.Torrent;
import io.reactivex.Flowable;
/**
* Available feature enum which can be implemented by clients. Use {@link Client#supports(Feature)} to see if a certain {@link Client} support a
* {@link Feature}.
*/
public enum Feature {
VERSION,
STARTING,
STOPPING,
RESUMING,
PAUSING
VERSION(Version.class),
LISTING(Listing.class),
STARTING_STOPPING(StartingStopping.class),
RESUMING_PAUSING(ResumingPausing.class),
FORCE_STARTING(ForceStarting.class);
private final Class<?> type;
Feature(Class<?> type) {
this.type = type;
}
public Class<?> type() {
return type;
}
public interface Version {
Flowable<String> clientVersion();
}
public interface Listing {
Flowable<Torrent> torrents();
}
public interface StartingStopping {
}
public interface ResumingPausing {
}
public interface ForceStarting {
Flowable<Torrent> forceStartTorrent();
}
}

22
connect/src/main/java/org/transdroid/connect/clients/UnsupportedFeatureException.java

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
package org.transdroid.connect.clients;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
/**
* Thrown when trying to call into a client method for a feature which the client does not support.
*/
public class UnsupportedFeatureException extends NotImplementedException {
private final Client client;
private final Feature feature;
UnsupportedFeatureException(Client client, Feature feature) {
this.client = client;
this.feature = feature;
}
public String getMessage() {
return client.name() + " does not support " + feature.name();
}
}

19
connect/src/main/java/org/transdroid/connect/clients/rtorrent/Rtorrent.java

@ -3,7 +3,6 @@ package org.transdroid.connect.clients.rtorrent; @@ -3,7 +3,6 @@ package org.transdroid.connect.clients.rtorrent;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import org.transdroid.connect.Configuration;
import org.transdroid.connect.clients.ClientSpec;
import org.transdroid.connect.clients.Feature;
import org.transdroid.connect.model.Torrent;
import org.transdroid.connect.model.TorrentStatus;
@ -11,8 +10,6 @@ import org.transdroid.connect.util.OkHttpBuilder; @@ -11,8 +10,6 @@ import org.transdroid.connect.util.OkHttpBuilder;
import org.transdroid.connect.util.RxUtil;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import io.reactivex.Flowable;
import io.reactivex.functions.Function;
@ -20,17 +17,11 @@ import nl.nl2312.xmlrpc.Nothing; @@ -20,17 +17,11 @@ import nl.nl2312.xmlrpc.Nothing;
import nl.nl2312.xmlrpc.XmlRpcConverterFactory;
import retrofit2.Retrofit;
public final class Rtorrent implements ClientSpec {
public static final Set<Feature> FEATURES = new HashSet<>();
{
FEATURES.add(Feature.VERSION);
FEATURES.add(Feature.STARTING);
FEATURES.add(Feature.STOPPING);
FEATURES.add(Feature.RESUMING);
FEATURES.add(Feature.PAUSING);
}
public final class Rtorrent implements
Feature.Version,
Feature.Listing,
Feature.StartingStopping,
Feature.ResumingPausing {
private final Configuration configuration;
private final Service service;

5
connect/src/main/java/org/transdroid/connect/clients/transmission/Transmission.java

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
package org.transdroid.connect.clients.transmission;
public final class Transmission {
}

21
connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentTest.java

@ -6,6 +6,7 @@ import org.transdroid.connect.Configuration; @@ -6,6 +6,7 @@ import org.transdroid.connect.Configuration;
import org.transdroid.connect.clients.Client;
import org.transdroid.connect.clients.ClientSpec;
import org.transdroid.connect.clients.Feature;
import org.transdroid.connect.clients.UnsupportedFeatureException;
import org.transdroid.connect.model.Torrent;
import java.io.IOException;
@ -21,17 +22,19 @@ public final class RtorrentTest { @@ -21,17 +22,19 @@ public final class RtorrentTest {
@Before
public void setUp() {
Configuration configuration = new Configuration(Client.RTORRENT, "http://localhost:8008/", "RPC2", null, null, true);
rtorrent = configuration.create();
rtorrent = new Configuration.Builder(Client.RTORRENT)
.baseUrl("http://localhost:8008/")
.endpoint("/RPC2")
.build()
.createClient();
}
@Test
public void features() {
assertThat(Client.RTORRENT.supports(Feature.VERSION)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.STARTING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.STOPPING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.RESUMING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.PAUSING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.STARTING_STOPPING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.RESUMING_PAUSING)).isTrue();
assertThat(Client.RTORRENT.supports(Feature.FORCE_STARTING)).isFalse();
}
@Test
@ -54,4 +57,10 @@ public final class RtorrentTest { @@ -54,4 +57,10 @@ public final class RtorrentTest {
});
}
@Test(expected = UnsupportedFeatureException.class)
public void forceStart() throws IOException {
rtorrent.forceStartTorrent()
.test();
}
}

Loading…
Cancel
Save