262 * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
263 *
264 * @return a {@code StackWalker} configured to skip all
265 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
266 * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
267 *
268 */
269 public static StackWalker getInstance() {
270 // no permission check needed
271 return DEFAULT_WALKER;
272 }
273
274 /**
275 * Returns a {@code StackWalker} instance with the given option specifying
276 * the stack frame information it can access.
277 *
278 * <p>
279 * If a security manager is present and the given {@code option} is
280 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
281 * it calls its {@link SecurityManager#checkPermission checkPermission}
282 * method for {@code StackFramePermission("retainClassReference")}.
283 *
284 * @param option {@link Option stack walking option}
285 *
286 * @return a {@code StackWalker} configured with the given option
287 *
288 * @throws SecurityException if a security manager exists and its
289 * {@code checkPermission} method denies access.
290 */
291 public static StackWalker getInstance(Option option) {
292 return getInstance(EnumSet.of(Objects.requireNonNull(option)));
293 }
294
295 /**
296 * Returns a {@code StackWalker} instance with the given {@code options} specifying
297 * the stack frame information it can access. If the given {@code options}
298 * is empty, this {@code StackWalker} is configured to skip all
299 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
300 * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
301 *
302 * <p>
303 * If a security manager is present and the given {@code options} contains
304 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
305 * it calls its {@link SecurityManager#checkPermission checkPermission}
306 * method for {@code StackFramePermission("retainClassReference")}.
307 *
308 * @param options {@link Option stack walking option}
309 *
310 * @return a {@code StackWalker} configured with the given options
311 *
312 * @throws SecurityException if a security manager exists and its
313 * {@code checkPermission} method denies access.
314 */
315 public static StackWalker getInstance(Set<Option> options) {
316 if (options.isEmpty()) {
317 return DEFAULT_WALKER;
318 }
319
320 EnumSet<Option> optionSet = toEnumSet(options);
321 checkPermission(optionSet);
322 return new StackWalker(optionSet);
323 }
324
325 /**
326 * Returns a {@code StackWalker} instance with the given {@code options} specifying
327 * the stack frame information it can access. If the given {@code options}
328 * is empty, this {@code StackWalker} is configured to skip all
329 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
330 * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
331 *
332 * <p>
333 * If a security manager is present and the given {@code options} contains
334 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
335 * it calls its {@link SecurityManager#checkPermission checkPermission}
336 * method for {@code StackFramePermission("retainClassReference")}.
337 *
338 * <p>
339 * The {@code estimateDepth} specifies the estimate number of stack frames
340 * this {@code StackWalker} will traverse that the {@code StackWalker} could
341 * use as a hint for the buffer size.
342 *
343 * @param options {@link Option stack walking options}
344 * @param estimateDepth Estimate number of stack frames to be traversed.
345 *
346 * @return a {@code StackWalker} configured with the given options
347 *
348 * @throws IllegalArgumentException if {@code estimateDepth <= 0}
349 * @throws SecurityException if a security manager exists and its
350 * {@code checkPermission} method denies access.
351 */
352 public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
353 if (estimateDepth <= 0) {
354 throw new IllegalArgumentException("estimateDepth must be > 0");
355 }
356 EnumSet<Option> optionSet = toEnumSet(options);
359 }
360
361 // ----- private constructors ------
362 private StackWalker(EnumSet<Option> options) {
363 this(options, 0, null);
364 }
365 private StackWalker(EnumSet<Option> options, int estimateDepth) {
366 this(options, estimateDepth, null);
367 }
368 private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
369 this.options = options;
370 this.estimateDepth = estimateDepth;
371 this.extendedOption = extendedOption;
372 }
373
374 private static void checkPermission(Set<Option> options) {
375 Objects.requireNonNull(options);
376 SecurityManager sm = System.getSecurityManager();
377 if (sm != null) {
378 if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
379 sm.checkPermission(new StackFramePermission("retainClassReference"));
380 }
381 }
382 }
383
384 /*
385 * Returns a defensive copy
386 */
387 private static EnumSet<Option> toEnumSet(Set<Option> options) {
388 Objects.requireNonNull(options);
389 if (options.isEmpty()) {
390 return DEFAULT_EMPTY_OPTION;
391 } else {
392 return EnumSet.copyOf(options);
393 }
394 }
395
396 /**
397 * Applies the given function to the stream of {@code StackFrame}s
398 * for the current thread, traversing from the top frame of the stack,
399 * which is the method calling this {@code walk} method.
|
262 * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
263 *
264 * @return a {@code StackWalker} configured to skip all
265 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
266 * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
267 *
268 */
269 public static StackWalker getInstance() {
270 // no permission check needed
271 return DEFAULT_WALKER;
272 }
273
274 /**
275 * Returns a {@code StackWalker} instance with the given option specifying
276 * the stack frame information it can access.
277 *
278 * <p>
279 * If a security manager is present and the given {@code option} is
280 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
281 * it calls its {@link SecurityManager#checkPermission checkPermission}
282 * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
283 *
284 * @param option {@link Option stack walking option}
285 *
286 * @return a {@code StackWalker} configured with the given option
287 *
288 * @throws SecurityException if a security manager exists and its
289 * {@code checkPermission} method denies access.
290 */
291 public static StackWalker getInstance(Option option) {
292 return getInstance(EnumSet.of(Objects.requireNonNull(option)));
293 }
294
295 /**
296 * Returns a {@code StackWalker} instance with the given {@code options} specifying
297 * the stack frame information it can access. If the given {@code options}
298 * is empty, this {@code StackWalker} is configured to skip all
299 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
300 * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
301 *
302 * <p>
303 * If a security manager is present and the given {@code options} contains
304 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
305 * it calls its {@link SecurityManager#checkPermission checkPermission}
306 * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
307 *
308 * @param options {@link Option stack walking option}
309 *
310 * @return a {@code StackWalker} configured with the given options
311 *
312 * @throws SecurityException if a security manager exists and its
313 * {@code checkPermission} method denies access.
314 */
315 public static StackWalker getInstance(Set<Option> options) {
316 if (options.isEmpty()) {
317 return DEFAULT_WALKER;
318 }
319
320 EnumSet<Option> optionSet = toEnumSet(options);
321 checkPermission(optionSet);
322 return new StackWalker(optionSet);
323 }
324
325 /**
326 * Returns a {@code StackWalker} instance with the given {@code options} specifying
327 * the stack frame information it can access. If the given {@code options}
328 * is empty, this {@code StackWalker} is configured to skip all
329 * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
330 * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
331 *
332 * <p>
333 * If a security manager is present and the given {@code options} contains
334 * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
335 * it calls its {@link SecurityManager#checkPermission checkPermission}
336 * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
337 *
338 * <p>
339 * The {@code estimateDepth} specifies the estimate number of stack frames
340 * this {@code StackWalker} will traverse that the {@code StackWalker} could
341 * use as a hint for the buffer size.
342 *
343 * @param options {@link Option stack walking options}
344 * @param estimateDepth Estimate number of stack frames to be traversed.
345 *
346 * @return a {@code StackWalker} configured with the given options
347 *
348 * @throws IllegalArgumentException if {@code estimateDepth <= 0}
349 * @throws SecurityException if a security manager exists and its
350 * {@code checkPermission} method denies access.
351 */
352 public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
353 if (estimateDepth <= 0) {
354 throw new IllegalArgumentException("estimateDepth must be > 0");
355 }
356 EnumSet<Option> optionSet = toEnumSet(options);
359 }
360
361 // ----- private constructors ------
362 private StackWalker(EnumSet<Option> options) {
363 this(options, 0, null);
364 }
365 private StackWalker(EnumSet<Option> options, int estimateDepth) {
366 this(options, estimateDepth, null);
367 }
368 private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
369 this.options = options;
370 this.estimateDepth = estimateDepth;
371 this.extendedOption = extendedOption;
372 }
373
374 private static void checkPermission(Set<Option> options) {
375 Objects.requireNonNull(options);
376 SecurityManager sm = System.getSecurityManager();
377 if (sm != null) {
378 if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
379 sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference"));
380 }
381 }
382 }
383
384 /*
385 * Returns a defensive copy
386 */
387 private static EnumSet<Option> toEnumSet(Set<Option> options) {
388 Objects.requireNonNull(options);
389 if (options.isEmpty()) {
390 return DEFAULT_EMPTY_OPTION;
391 } else {
392 return EnumSet.copyOf(options);
393 }
394 }
395
396 /**
397 * Applies the given function to the stream of {@code StackFrame}s
398 * for the current thread, traversing from the top frame of the stack,
399 * which is the method calling this {@code walk} method.
|