16
16
package io .micrometer .context ;
17
17
18
18
import java .util .HashMap ;
19
- import java .util .HashSet ;
20
19
import java .util .Map ;
21
- import java .util .Set ;
22
20
import java .util .function .Predicate ;
23
21
24
22
/**
@@ -31,11 +29,11 @@ final class DefaultContextSnapshot extends HashMap<Object, Object> implements Co
31
29
32
30
private static final ContextSnapshot emptyContextSnapshot = new DefaultContextSnapshot (new ContextRegistry ());
33
31
34
- private final ContextRegistry accessorRegistry ;
32
+ private final ContextRegistry contextRegistry ;
35
33
36
34
37
- DefaultContextSnapshot (ContextRegistry accessorRegistry ) {
38
- this .accessorRegistry = accessorRegistry ;
35
+ DefaultContextSnapshot (ContextRegistry contextRegistry ) {
36
+ this .contextRegistry = contextRegistry ;
39
37
}
40
38
41
39
@@ -48,7 +46,7 @@ public <C> C updateContext(C context) {
48
46
public <C > C updateContext (C context , Predicate <Object > keyPredicate ) {
49
47
if (!isEmpty ()) {
50
48
Map <Object , Object > valuesToWrite = new HashMap <>();
51
- forEach ((key , value ) -> {
49
+ this . forEach ((key , value ) -> {
52
50
if (keyPredicate .test (key )) {
53
51
valuesToWrite .put (key , value );
54
52
}
@@ -61,7 +59,7 @@ public <C> C updateContext(C context, Predicate<Object> keyPredicate) {
61
59
@ SuppressWarnings ("unchecked" )
62
60
private <C > C updateContextInternal (C context , Map <Object , Object > valueContainer ) {
63
61
if (!isEmpty ()) {
64
- ContextAccessor <?, ?> accessor = this .accessorRegistry .getContextAccessorForWrite (context );
62
+ ContextAccessor <?, ?> accessor = this .contextRegistry .getContextAccessorForWrite (context );
65
63
context = ((ContextAccessor <?, C >) accessor ).writeValues (valueContainer , context );
66
64
}
67
65
return context ;
@@ -74,27 +72,41 @@ public Scope setThreadLocalValues() {
74
72
75
73
@ Override
76
74
public Scope setThreadLocalValues (Predicate <Object > keyPredicate ) {
77
- Set <Object > keys = null ;
78
75
Map <Object , Object > previousValues = null ;
79
- for (ThreadLocalAccessor <?> accessor : this .accessorRegistry .getThreadLocalAccessors ()) {
76
+ for (ThreadLocalAccessor <?> accessor : this .contextRegistry .getThreadLocalAccessors ()) {
80
77
Object key = accessor .key ();
81
- if (keyPredicate .test (key ) && containsKey (key )) {
82
- keys = (keys != null ? keys : new HashSet <>());
83
- keys .add (key );
84
-
85
- Object previousValue = accessor .getValue ();
86
- previousValues = (previousValues != null ? previousValues : new HashMap <>());
87
- previousValues .put (key , previousValue );
88
-
89
- setThreadLocalValue (key , accessor );
78
+ if (keyPredicate .test (key ) && this .containsKey (key )) {
79
+ previousValues = setThreadLocal (key , get (key ), accessor , previousValues );
90
80
}
91
81
}
92
- return ( keys != null ? new DefaultScope ( keys , previousValues ) : () -> { } );
82
+ return DefaultScope . from ( previousValues , this . contextRegistry );
93
83
}
94
84
95
85
@ SuppressWarnings ("unchecked" )
96
- private <V > void setThreadLocalValue (Object key , ThreadLocalAccessor <?> accessor ) {
97
- ((ThreadLocalAccessor <V >) accessor ).setValue ((V ) get (key ));
86
+ private static <V > Map <Object , Object > setThreadLocal (
87
+ Object key , V value , ThreadLocalAccessor <?> accessor , @ Nullable Map <Object , Object > previousValues ) {
88
+
89
+ previousValues = (previousValues != null ? previousValues : new HashMap <>());
90
+ previousValues .put (key , accessor .getValue ());
91
+ ((ThreadLocalAccessor <V >) accessor ).setValue (value );
92
+ return previousValues ;
93
+ }
94
+
95
+ @ SuppressWarnings ("unchecked" )
96
+ static <C > Scope setThreadLocalsFrom (Object context , ContextRegistry registry , String ... keys ) {
97
+ ContextAccessor <?, ?> contextAccessor = registry .getContextAccessorForRead (context );
98
+ Map <Object , Object > previousValues = null ;
99
+ for (String key : keys ) {
100
+ Object value = ((ContextAccessor <C , ?>) contextAccessor ).readValue ((C ) context , key );
101
+ if (value != null ) {
102
+ for (ThreadLocalAccessor <?> threadLocalAccessor : registry .getThreadLocalAccessors ()) {
103
+ if (key .equals (threadLocalAccessor .key ())) {
104
+ previousValues = setThreadLocal (key , value , threadLocalAccessor , previousValues );
105
+ }
106
+ }
107
+ }
108
+ }
109
+ return DefaultScope .from (previousValues , registry );
98
110
}
99
111
100
112
@ SuppressWarnings ("unchecked" )
@@ -128,21 +140,21 @@ public String toString() {
128
140
/**
129
141
* Default implementation of {@link Scope}.
130
142
*/
131
- private class DefaultScope implements Scope {
132
-
133
- private final Set <Object > keys ;
143
+ private static class DefaultScope implements Scope {
134
144
135
145
private final Map <Object , Object > previousValues ;
136
146
137
- private DefaultScope (Set <Object > keys , Map <Object , Object > previousValues ) {
138
- this .keys = keys ;
147
+ private final ContextRegistry contextRegistry ;
148
+
149
+ private DefaultScope (Map <Object , Object > previousValues , ContextRegistry contextRegistry ) {
139
150
this .previousValues = previousValues ;
151
+ this .contextRegistry = contextRegistry ;
140
152
}
141
153
142
154
@ Override
143
155
public void close () {
144
- for (ThreadLocalAccessor <?> accessor : accessorRegistry .getThreadLocalAccessors ()) {
145
- if (this .keys . contains (accessor .key ())) {
156
+ for (ThreadLocalAccessor <?> accessor : this . contextRegistry .getThreadLocalAccessors ()) {
157
+ if (this .previousValues . containsKey (accessor .key ())) {
146
158
Object previousValue = this .previousValues .get (accessor .key ());
147
159
resetThreadLocalValue (accessor , previousValue );
148
160
}
@@ -158,6 +170,11 @@ private <V> void resetThreadLocalValue(ThreadLocalAccessor<?> accessor, @Nullabl
158
170
accessor .reset ();
159
171
}
160
172
}
173
+
174
+ public static Scope from (@ Nullable Map <Object , Object > previousValues , ContextRegistry registry ) {
175
+ return (previousValues != null ? new DefaultScope (previousValues , registry ) : () -> { });
176
+ }
177
+
161
178
}
162
179
163
180
}
0 commit comments