-
Notifications
You must be signed in to change notification settings - Fork 7.6k
/
Copy pathSubscriptions.java
135 lines (121 loc) · 4.44 KB
/
Subscriptions.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* Copyright 2014 Netflix, Inc.
*
* 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 rx.subscriptions;
import java.util.concurrent.Future;
import rx.Subscription;
import rx.functions.Action0;
/**
* Helper methods and utilities for creating and working with {@link Subscription} objects
*/
public final class Subscriptions {
/**
* A {@link Subscription} that does nothing when its unsubscribe method is called.
*/
private static final Unsubscribed UNSUBSCRIBED = new Unsubscribed();
private Subscriptions() {
throw new IllegalStateException("No instances!");
}
/**
* Returns a {@link Subscription} to which {@code unsubscribe} does nothing except to change
* {@code isUnsubscribed} to {@code true}. It's stateful and {@code isUnsubscribed} indicates if
* {@code unsubscribe} is called, which is different from {@link #unsubscribed()}.
*
* <pre><code>
* Subscription empty = Subscriptions.empty();
* System.out.println(empty.isUnsubscribed()); // false
* empty.unsubscribe();
* System.out.println(empty.isUnsubscribed()); // true
* </code></pre>
*
* @return a {@link Subscription} to which {@code unsubscribe} does nothing except to change
* {@code isUnsubscribed} to {@code true}
*/
public static Subscription empty() {
return BooleanSubscription.create();
}
/**
* Returns a {@link Subscription} to which {@code unsubscribe} does nothing, as it is already unsubscribed.
* Its {@code isUnsubscribed} always returns {@code true}, which is different from {@link #empty()}.
*
* <pre><code>
* Subscription unsubscribed = Subscriptions.unsubscribed();
* System.out.println(unsubscribed.isUnsubscribed()); // true
* </code></pre>
*
* @return a {@link Subscription} to which {@code unsubscribe} does nothing, as it is already unsubscribed
* @since 1.1.0
*/
public static Subscription unsubscribed() {
return UNSUBSCRIBED;
}
/**
* Creates and returns a {@link Subscription} that invokes the given {@link Action0} when unsubscribed.
*
* @param unsubscribe
* Action to invoke on unsubscribe.
* @return {@link Subscription}
*/
public static Subscription create(final Action0 unsubscribe) {
return BooleanSubscription.create(unsubscribe);
}
/**
* Converts a {@link Future} into a {@link Subscription} and cancels it when unsubscribed.
*
* @param f
* the {@link Future} to convert
* @return a {@link Subscription} that wraps {@code f}
*/
public static Subscription from(final Future<?> f) {
return new FutureSubscription(f);
}
/** Naming classes helps with debugging. */
static final class FutureSubscription implements Subscription {
final Future<?> f;
public FutureSubscription(Future<?> f) {
this.f = f;
}
@Override
public void unsubscribe() {
f.cancel(true);
}
@Override
public boolean isUnsubscribed() {
return f.isCancelled();
}
}
/**
* Converts a set of {@link Subscription}s into a {@link CompositeSubscription} that groups the multiple
* Subscriptions together and unsubscribes from all of them together.
*
* @param subscriptions
* the Subscriptions to group together
* @return a {@link CompositeSubscription} representing the {@code subscriptions} set
*/
public static CompositeSubscription from(Subscription... subscriptions) {
return new CompositeSubscription(subscriptions);
}
/** Naming classes helps with debugging. */
static final class Unsubscribed implements Subscription {
@Override
public void unsubscribe() {
// deliberately ignored
}
@Override
public boolean isUnsubscribed() {
return true;
}
}
}