35
35
import org .joda .time .ReadableDateTime ;
36
36
37
37
import java .io .IOException ;
38
+ import java .security .AccessController ;
39
+ import java .security .PrivilegedAction ;
38
40
import java .util .AbstractList ;
39
41
import java .util .Arrays ;
40
42
import java .util .Comparator ;
41
43
import java .util .List ;
44
+ import java .util .function .Consumer ;
42
45
import java .util .function .UnaryOperator ;
43
46
44
47
45
48
/**
46
49
* Script level doc values, the assumption is that any implementation will
47
50
* implement a <code>getValue</code> and a <code>getValues</code> that return
48
51
* the relevant type that then can be used in scripts.
49
- *
52
+ *
50
53
* Implementations should not internally re-use objects for the values that they
51
54
* return as a single {@link ScriptDocValues} instance can be reused to return
52
55
* values form multiple documents.
@@ -94,14 +97,30 @@ public static final class Longs extends ScriptDocValues<Long> {
94
97
protected static final DeprecationLogger deprecationLogger = new DeprecationLogger (ESLoggerFactory .getLogger (Longs .class ));
95
98
96
99
private final SortedNumericDocValues in ;
100
+ /**
101
+ * Callback for deprecated fields. In production this should always point to
102
+ * {@link #deprecationLogger} but tests will override it so they can test that
103
+ * we use the required permissions when calling it.
104
+ */
105
+ private final Consumer <String > deprecationCallback ;
97
106
private long [] values = new long [0 ];
98
107
private int count ;
99
108
private Dates dates ;
100
109
private int docId = -1 ;
101
110
111
+ /**
112
+ * Standard constructor.
113
+ */
102
114
public Longs (SortedNumericDocValues in ) {
103
- this .in = in ;
115
+ this (in , deprecationLogger ::deprecated );
116
+ }
104
117
118
+ /**
119
+ * Constructor for testing the deprecation callback.
120
+ */
121
+ Longs (SortedNumericDocValues in , Consumer <String > deprecationCallback ) {
122
+ this .in = in ;
123
+ this .deprecationCallback = deprecationCallback ;
105
124
}
106
125
107
126
@ Override
@@ -142,7 +161,7 @@ public long getValue() {
142
161
143
162
@ Deprecated
144
163
public ReadableDateTime getDate () throws IOException {
145
- deprecationLogger . deprecated ("getDate on numeric fields is deprecated. Use a date field to get dates." );
164
+ deprecated ("getDate on numeric fields is deprecated. Use a date field to get dates." );
146
165
if (dates == null ) {
147
166
dates = new Dates (in );
148
167
dates .setNextDocId (docId );
@@ -152,7 +171,7 @@ public ReadableDateTime getDate() throws IOException {
152
171
153
172
@ Deprecated
154
173
public List <ReadableDateTime > getDates () throws IOException {
155
- deprecationLogger . deprecated ("getDates on numeric fields is deprecated. Use a date field to get dates." );
174
+ deprecated ("getDates on numeric fields is deprecated. Use a date field to get dates." );
156
175
if (dates == null ) {
157
176
dates = new Dates (in );
158
177
dates .setNextDocId (docId );
@@ -169,6 +188,22 @@ public Long get(int index) {
169
188
public int size () {
170
189
return count ;
171
190
}
191
+
192
+ /**
193
+ * Log a deprecation log, with the server's permissions, not the permissions of the
194
+ * script calling this method. We need to do this to prevent errors when rolling
195
+ * the log file.
196
+ */
197
+ private void deprecated (String message ) {
198
+ // Intentionally not calling SpecialPermission.check because this is supposed to be called by scripts
199
+ AccessController .doPrivileged (new PrivilegedAction <Void >() {
200
+ @ Override
201
+ public Void run () {
202
+ deprecationCallback .accept (message );
203
+ return null ;
204
+ }
205
+ });
206
+ }
172
207
}
173
208
174
209
public static final class Dates extends ScriptDocValues <ReadableDateTime > {
@@ -177,15 +212,32 @@ public static final class Dates extends ScriptDocValues<ReadableDateTime> {
177
212
private static final ReadableDateTime EPOCH = new DateTime (0 , DateTimeZone .UTC );
178
213
179
214
private final SortedNumericDocValues in ;
215
+ /**
216
+ * Callback for deprecated fields. In production this should always point to
217
+ * {@link #deprecationLogger} but tests will override it so they can test that
218
+ * we use the required permissions when calling it.
219
+ */
220
+ private final Consumer <String > deprecationCallback ;
180
221
/**
181
222
* Values wrapped in {@link MutableDateTime}. Null by default an allocated on first usage so we allocate a reasonably size. We keep
182
223
* this array so we don't have allocate new {@link MutableDateTime}s on every usage. Instead we reuse them for every document.
183
224
*/
184
225
private MutableDateTime [] dates ;
185
226
private int count ;
186
227
228
+ /**
229
+ * Standard constructor.
230
+ */
187
231
public Dates (SortedNumericDocValues in ) {
232
+ this (in , deprecationLogger ::deprecated );
233
+ }
234
+
235
+ /**
236
+ * Constructor for testing deprecation logging.
237
+ */
238
+ Dates (SortedNumericDocValues in , Consumer <String > deprecationCallback ) {
188
239
this .in = in ;
240
+ this .deprecationCallback = deprecationCallback ;
189
241
}
190
242
191
243
/**
@@ -204,7 +256,7 @@ public ReadableDateTime getValue() {
204
256
*/
205
257
@ Deprecated
206
258
public ReadableDateTime getDate () {
207
- deprecationLogger . deprecated ("getDate is no longer necessary on date fields as the value is now a date." );
259
+ deprecated ("getDate is no longer necessary on date fields as the value is now a date." );
208
260
return getValue ();
209
261
}
210
262
@@ -213,7 +265,7 @@ public ReadableDateTime getDate() {
213
265
*/
214
266
@ Deprecated
215
267
public List <ReadableDateTime > getDates () {
216
- deprecationLogger . deprecated ("getDates is no longer necessary on date fields as the values are now dates." );
268
+ deprecated ("getDates is no longer necessary on date fields as the values are now dates." );
217
269
return this ;
218
270
}
219
271
@@ -274,6 +326,22 @@ void refreshArray() throws IOException {
274
326
dates [i ] = new MutableDateTime (in .nextValue (), DateTimeZone .UTC );
275
327
}
276
328
}
329
+
330
+ /**
331
+ * Log a deprecation log, with the server's permissions, not the permissions of the
332
+ * script calling this method. We need to do this to prevent errors when rolling
333
+ * the log file.
334
+ */
335
+ private void deprecated (String message ) {
336
+ // Intentionally not calling SpecialPermission.check because this is supposed to be called by scripts
337
+ AccessController .doPrivileged (new PrivilegedAction <Void >() {
338
+ @ Override
339
+ public Void run () {
340
+ deprecationCallback .accept (message );
341
+ return null ;
342
+ }
343
+ });
344
+ }
277
345
}
278
346
279
347
public static final class Doubles extends ScriptDocValues <Double > {
0 commit comments