287 |
|
|
288 |
|
/** |
289 |
|
* Creates and returns a {@link Callable} object that, when |
290 |
< |
* called, runs the given privileged exception action and returns its result |
290 |
> |
* called, runs the given privileged exception action and returns |
291 |
> |
* its result |
292 |
|
* @param action the privileged exception action to run |
293 |
|
*/ |
294 |
|
public static Callable<Object> callable(PrivilegedExceptionAction action) { |
296 |
|
} |
297 |
|
|
298 |
|
/** |
299 |
+ |
* Creates and returns a {@link Callable} object that will, when |
300 |
+ |
* called, execute the given <tt>callable</tt> under the current |
301 |
+ |
* access control context. This method should normally be |
302 |
+ |
* invoked within an {@link AccessController#doPrivileged} action |
303 |
+ |
* to create callables that will, if possible, execute under the |
304 |
+ |
* selected permission settings holding within that action; or if |
305 |
+ |
* not possible, throw an associated {@link |
306 |
+ |
* AccessControlException}. |
307 |
+ |
* @param callable the underlying task |
308 |
+ |
* |
309 |
+ |
*/ |
310 |
+ |
public static <T> Callable<T> privilegedCallable(Callable<T> callable) { |
311 |
+ |
return new PrivilegedCallable(callable); |
312 |
+ |
} |
313 |
+ |
|
314 |
+ |
/** |
315 |
+ |
* Creates and returns a {@link Callable} object that will, when |
316 |
+ |
* called, execute the given <tt>callable</tt> under the current |
317 |
+ |
* access control context, with the current context class loader |
318 |
+ |
* as the context class loader. This method should normally be |
319 |
+ |
* invoked within an {@link AccessController#doPrivileged} action |
320 |
+ |
* to create callables that will, if possible, execute under the |
321 |
+ |
* selected permission settings holding within that action; or if |
322 |
+ |
* not possible, throw an associated {@link |
323 |
+ |
* AccessControlException}. |
324 |
+ |
* @param callable the underlying task |
325 |
+ |
* |
326 |
+ |
* @throws AccessControlException if the current access control |
327 |
+ |
* context does not have permission to both set and get context |
328 |
+ |
* class loader. |
329 |
+ |
*/ |
330 |
+ |
public static <T> Callable<T> privilegedCallableUsingCurrentClassLoader(Callable<T> callable) { |
331 |
+ |
return new PrivilegedCallableUsingCurrentClassLoader(callable); |
332 |
+ |
} |
333 |
+ |
|
334 |
+ |
|
335 |
+ |
/** |
336 |
|
* A callable that runs given task and returns given result |
337 |
|
*/ |
338 |
|
static class RunnableAdapter<T> implements Callable<T> { |
374 |
|
private final PrivilegedExceptionAction action; |
375 |
|
} |
376 |
|
|
377 |
+ |
|
378 |
+ |
/** |
379 |
+ |
* A callable that runs under established access control settings |
380 |
+ |
*/ |
381 |
+ |
static class PrivilegedCallable<T> implements Callable<T> { |
382 |
+ |
private final AccessControlContext acc; |
383 |
+ |
private final Callable<T> task; |
384 |
+ |
T result; |
385 |
+ |
Exception exception; |
386 |
+ |
PrivilegedCallable(Callable<T> task) { |
387 |
+ |
this.task = task; |
388 |
+ |
this.acc = AccessController.getContext(); |
389 |
+ |
} |
390 |
+ |
|
391 |
+ |
public T call() throws Exception { |
392 |
+ |
AccessController.doPrivileged(new PrivilegedAction() { |
393 |
+ |
public Object run() { |
394 |
+ |
try { |
395 |
+ |
result = task.call(); |
396 |
+ |
} catch(Exception ex) { |
397 |
+ |
exception = ex; |
398 |
+ |
} |
399 |
+ |
return null; |
400 |
+ |
} |
401 |
+ |
}, acc); |
402 |
+ |
if (exception != null) |
403 |
+ |
throw exception; |
404 |
+ |
else |
405 |
+ |
return result; |
406 |
+ |
} |
407 |
+ |
} |
408 |
+ |
|
409 |
+ |
/** |
410 |
+ |
* A callable that runs under established access control settings and |
411 |
+ |
* current ClassLoader |
412 |
+ |
*/ |
413 |
+ |
static class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> { |
414 |
+ |
private final ClassLoader ccl; |
415 |
+ |
private final AccessControlContext acc; |
416 |
+ |
private final Callable<T> task; |
417 |
+ |
T result; |
418 |
+ |
Exception exception; |
419 |
+ |
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) { |
420 |
+ |
this.task = task; |
421 |
+ |
this.ccl = Thread.currentThread().getContextClassLoader(); |
422 |
+ |
this.acc = AccessController.getContext(); |
423 |
+ |
acc.checkPermission(new RuntimePermission("getContextClassLoader")); |
424 |
+ |
acc.checkPermission(new RuntimePermission("setContextClassLoader")); |
425 |
+ |
} |
426 |
+ |
|
427 |
+ |
public T call() throws Exception { |
428 |
+ |
AccessController.doPrivileged(new PrivilegedAction() { |
429 |
+ |
public Object run() { |
430 |
+ |
ClassLoader savedcl = null; |
431 |
+ |
Thread t = Thread.currentThread(); |
432 |
+ |
try { |
433 |
+ |
ClassLoader cl = t.getContextClassLoader(); |
434 |
+ |
if (ccl != cl) { |
435 |
+ |
t.setContextClassLoader(ccl); |
436 |
+ |
savedcl = cl; |
437 |
+ |
} |
438 |
+ |
result = task.call(); |
439 |
+ |
} catch(Exception ex) { |
440 |
+ |
exception = ex; |
441 |
+ |
} finally { |
442 |
+ |
if (savedcl != null) |
443 |
+ |
t.setContextClassLoader(savedcl); |
444 |
+ |
} |
445 |
+ |
return null; |
446 |
+ |
} |
447 |
+ |
}, acc); |
448 |
+ |
if (exception != null) |
449 |
+ |
throw exception; |
450 |
+ |
else |
451 |
+ |
return result; |
452 |
+ |
} |
453 |
+ |
} |
454 |
+ |
|
455 |
|
static class DefaultThreadFactory implements ThreadFactory { |
456 |
|
static final AtomicInteger poolNumber = new AtomicInteger(1); |
457 |
|
final ThreadGroup group; |
528 |
|
public <T> Future<T> submit(Callable<T> task) { |
529 |
|
return e.submit(task); |
530 |
|
} |
415 |
– |
|
416 |
– |
public <T> T invoke(Callable<T> task) throws ExecutionException, InterruptedException { |
417 |
– |
return e.invoke(task); |
418 |
– |
} |
531 |
|
public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks) |
532 |
|
throws InterruptedException { |
533 |
|
return e.invokeAll(tasks); |