content: package com.achuna33.Gadgets.utils;
  
  
  import java.security.Permission;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.concurrent.Callable;
  
  // TODO per-thread secmgr
  public class ExecCheckingSecurityManager extends SecurityManager {
      public ExecCheckingSecurityManager() {
          this(true);
      }
  
      public ExecCheckingSecurityManager(boolean throwException) {
          this.throwException = throwException;
      }
  
      private final boolean throwException;
  
      private final List<String> cmds = new LinkedList<String>();
  
      public List<String> getCmds() {
          return Collections.unmodifiableList(cmds);
      }
  
      @Override
      public void checkPermission(final Permission perm) { }
  
      @Override
      public void checkPermission(final Permission perm, final Object context) { }
  
      @Override
      public void checkExec(final String cmd) {
          super.checkExec(cmd);
  
          cmds.add(cmd);
  
          if (throwException) {
              // throw a special exception to ensure we can detect exec() in the test
              throw new ExecException(cmd);
          }
      };
  
      @SuppressWarnings("serial")
      public static class ExecException extends RuntimeException {
          private final String threadName = Thread.currentThread().getName();
          private final String cmd;
          public ExecException(String cmd) { this.cmd = cmd; }
          public String getCmd() { return cmd; }
          public String getThreadName() { return threadName; }
          @
                  Override
          public String getMessage() {
              return "executed `" + getCmd() + "` in [" + getThreadName() + "]";
          }
      }
  
      public void callWrapped(final Runnable runnable) throws Exception {
          callWrapped(new Callable<Void>(){
              public Void call() throws Exception {
                  runnable.run();
                  return null;
              }
          });
      }
  
      public <T> T callWrapped(final Callable<T> callable) throws Exception {
          SecurityManager sm = System.getSecurityManager(); // save sm
          System.setSecurityManager(this);
          try {
              T result = callable.call();
              if (throwException && ! getCmds().isEmpty()) {
                  throw new ExecException(getCmds().get(0));
              }
              return result;
          } catch (Exception e) {
              if (! (e instanceof ExecException) && throwException && ! getCmds().isEmpty()) {
                  throw new ExecException(getCmds().get(0));
              } else {
                  throw e;
              }
          } finally {
              System.setSecurityManager(sm); // restore sm
          }
      }
  }
  