15
15
*/
16
16
package org .springframework .cache .interceptor ;
17
17
18
- import org .springframework .util .Assert ;
18
+ import org .springframework .core .ReactiveAdapter ;
19
+ import org .springframework .core .ReactiveAdapterRegistry ;
19
20
import org .springframework .util .ClassUtils ;
20
21
import org .springframework .util .ObjectUtils ;
21
- import rx .Observable ;
22
- import rx .functions .Action0 ;
23
- import rx .functions .Action1 ;
22
+ import reactor .core .publisher .Mono ;
23
+ import rx .Single ;
24
24
25
- import java .util .*;
25
+ import java .util .HashMap ;
26
+ import java .util .Map ;
27
+ import java .util .Optional ;
28
+ import java .util .function .Supplier ;
26
29
27
30
/**
28
31
* Manages the {@link CacheResultWrapper} instances to apply only the appropriate.
@@ -32,29 +35,41 @@ public class CacheResultWrapperManager {
32
35
private Map <Class <?>, CacheResultWrapper > unwrapperByClass ;
33
36
34
37
public CacheResultWrapperManager () {
35
- unwrapperByClass = new HashMap <Class <?>, CacheResultWrapper >();
38
+ unwrapperByClass = new HashMap <>();
36
39
37
- List <CacheResultWrapper > unwrapperList = new ArrayList <CacheResultWrapper >();
40
+ unwrapperByClass .put (Optional .class , new OptionalUnWrapper ());
41
+ registerReactiveWrappers ();
42
+ }
38
43
39
- unwrapperList .add (new OptionalUnWrapper ());
44
+ private void registerReactiveWrappers () {
45
+ if (tryRegisterResultWrapper ("reactor.core.publisher.Mono" , MonoReactiveWrapper ::new )) {
46
+ ReactiveAdapterRegistry adapterRegistry = new ReactiveAdapterRegistry ();
40
47
41
- if (ClassUtils .isPresent ("rx.Observable" , CacheAspectSupport .class .getClassLoader ())) {
42
- unwrapperList .add (new ObservableWrapper ());
48
+ tryRegisterResultWrapper ("rx.Single" , () -> new SingleReactiveWrapper (adapterRegistry ));
43
49
}
50
+ }
44
51
45
- for (CacheResultWrapper unwrapper : unwrapperList ) {
46
- unwrapperByClass .put (unwrapper .getWrapClass (), unwrapper );
52
+ private boolean tryRegisterResultWrapper (String className , Supplier <CacheResultWrapper > cacheResultWrapperSupplier ) {
53
+ try {
54
+ Class <?> clazz = ClassUtils .forName (className , CacheAspectSupport .class .getClassLoader ());
55
+ CacheResultWrapper cacheResultWrapper = cacheResultWrapperSupplier .get ();
56
+ unwrapperByClass .put (clazz , cacheResultWrapper );
57
+ return true ;
58
+ } catch (ClassNotFoundException e ) {
59
+ // Cannot register wrapper
60
+ return false ;
47
61
}
48
62
}
49
63
50
64
/**
51
65
* Wraps a value
66
+ *
52
67
* @param clazz the target class wanted
53
68
* @param value the value to be wrapped
54
69
* @return the value wrapped if it can, or the same value if it cannot handle it
55
70
*/
56
71
public Object wrap (Class <?> clazz , Object value ) {
57
- if (value != null ) {
72
+ if (value != null ) {
58
73
CacheResultWrapper unwrapper = unwrapperByClass .get (clazz );
59
74
60
75
if (unwrapper != null ) {
@@ -67,16 +82,17 @@ public Object wrap(Class<?> clazz, Object value) {
67
82
68
83
/**
69
84
* Unwraps the value asynchronously
85
+ *
70
86
* @param valueWrapped the value wrapped to be unwrapped
71
- * @param asyncResult where the result will be notified
87
+ * @param asyncResult where the result will be notified
72
88
* @return the same value wrapped or decorated in order to notify when it finish.
73
89
*/
74
- public Object asyncUnwrap (Object valueWrapped , AsyncWrapResult asyncResult ) {
75
- if (valueWrapped != null ) {
76
- CacheResultWrapper unwrapper = unwrapperByClass .get (valueWrapped . getClass () );
90
+ public Object asyncUnwrap (Object valueWrapped , Class <?> classWrapped , AsyncWrapResult asyncResult ) {
91
+ if (valueWrapped != null ) {
92
+ CacheResultWrapper unwrapper = unwrapperByClass .get (classWrapped );
77
93
78
94
if (unwrapper != null ) {
79
- return unwrapper .unwrap (valueWrapped , asyncResult );
95
+ return unwrapper .notifyResult (valueWrapped , asyncResult );
80
96
}
81
97
}
82
98
@@ -85,77 +101,73 @@ public Object asyncUnwrap(Object valueWrapped, AsyncWrapResult asyncResult) {
85
101
return valueWrapped ;
86
102
}
87
103
104
+ private class SingleReactiveWrapper extends MonoReactiveAdapterWrapper {
105
+ public SingleReactiveWrapper (ReactiveAdapterRegistry registry ) {
106
+ super (registry , Single .class );
107
+ }
108
+ }
88
109
89
- /**
90
- * Inner class to avoid a hard dependency on Java 8.
91
- */
92
- private class OptionalUnWrapper implements CacheResultWrapper {
110
+ private class MonoReactiveWrapper implements CacheResultWrapper {
111
+ @ Override
112
+ public Mono <?> wrap (Object value ) {
113
+ return Mono .justOrEmpty (value );
114
+ }
93
115
94
116
@ Override
95
- public Object unwrap (Object optionalObject , AsyncWrapResult asyncResult ) {
96
- Optional <?> optional = (Optional <?>) optionalObject ;
117
+ public Mono <?> notifyResult (Object objectWrapped , AsyncWrapResult asyncResult ) {
118
+ Mono <?> monoWrapped = (Mono <?>) objectWrapped ;
97
119
98
- Object value = ObjectUtils .unwrapOptional (optional );
120
+ return monoWrapped
121
+ .doOnSuccess (asyncResult ::complete )
122
+ .doOnError (asyncResult ::error );
123
+ }
124
+ }
99
125
100
- asyncResult .complete (value );
101
126
102
- return optionalObject ;
127
+ private abstract class MonoReactiveAdapterWrapper implements CacheResultWrapper {
128
+ private ReactiveAdapter adapter ;
129
+ private MonoReactiveWrapper monoReactiveWrapper ;
130
+
131
+ MonoReactiveAdapterWrapper (ReactiveAdapterRegistry registry , Class <?> wrapperClass ) {
132
+ this .adapter = registry .getAdapterFrom (wrapperClass );
133
+ this .monoReactiveWrapper = new MonoReactiveWrapper ();
103
134
}
104
135
136
+ @ SuppressWarnings ("unchecked" )
105
137
@ Override
106
- public Class <?> getWrapClass ( ) {
107
- return Optional . class ;
138
+ public Object wrap ( Object value ) {
139
+ return adapter . fromPublisher ( monoReactiveWrapper . wrap ( value )) ;
108
140
}
109
141
142
+ @ SuppressWarnings ("unchecked" )
110
143
@ Override
111
- public Object wrap (Object value ) {
112
- return Optional .ofNullable (value );
144
+ public Object notifyResult (Object valueWrapped , AsyncWrapResult asyncResult ) {
145
+ Mono <?> monoWrapped = adapter .toMono (valueWrapped );
146
+ Mono <?> monoCacheWrapped = monoReactiveWrapper .notifyResult (monoWrapped , asyncResult );
147
+
148
+ return adapter .fromPublisher (monoCacheWrapped );
113
149
}
114
150
}
115
151
116
- private class ObservableWrapper implements CacheResultWrapper {
152
+ /**
153
+ * Inner class to avoid a hard dependency on Java 8.
154
+ */
155
+ private class OptionalUnWrapper implements CacheResultWrapper {
117
156
118
157
@ Override
119
- public Object wrap (Object value ) {
120
- if (value instanceof Iterable ) {
121
- return Observable .from ((Iterable <?>) value );
122
- }
123
- else {
124
- // Not sure if it's a good idea... At least a warning maybe be a good idea
125
- return Observable .just (value );
126
- }
127
- }
158
+ public Optional <?> notifyResult (Object optionalObject , AsyncWrapResult asyncResult ) {
159
+ Optional <?> optional = (Optional <?>) optionalObject ;
128
160
129
- @ Override
130
- public Object unwrap (Object valueWrapped , final AsyncWrapResult asyncResult ) {
131
- Observable <?> valueObservable = (Observable <?>) valueWrapped ;
132
-
133
- final List <Object > values = new ArrayList <Object >();
134
-
135
- return valueObservable
136
- .doOnNext (new Action1 <Object >() {
137
- @ Override
138
- public void call (Object o ) {
139
- values .add (o );
140
- }
141
- })
142
- .doOnCompleted (new Action0 () {
143
- @ Override
144
- public void call () {
145
- asyncResult .complete (values );
146
- }
147
- })
148
- .doOnError (new Action1 <Throwable >() {
149
- @ Override
150
- public void call (Throwable throwable ) {
151
- asyncResult .error (throwable );
152
- }
153
- });
161
+ Object value = ObjectUtils .unwrapOptional (optional );
162
+
163
+ asyncResult .complete (value );
164
+
165
+ return optional ;
154
166
}
155
167
156
168
@ Override
157
- public Class <?> getWrapClass ( ) {
158
- return Observable . class ;
169
+ public Optional <?> wrap ( Object value ) {
170
+ return Optional . ofNullable ( value ) ;
159
171
}
160
172
}
161
173
}
0 commit comments