/**
  * Constructs a {@link UnrestrictedSessionRunner} given an existing session (which may or may not
  * be already unrestricted).
  *
  * <p>Originating user is taken on given session.
  *
  * @param session the available session
  */
 protected UnrestrictedSessionRunner(CoreSession session) {
   this.session = session;
   sessionIsAlreadyUnrestricted = isUnrestricted(session);
   if (sessionIsAlreadyUnrestricted) {
     repositoryName = null;
   } else {
     repositoryName = session.getRepositoryName();
   }
   Principal pal = session.getPrincipal();
   if (pal != null) {
     originatingUsername = pal.getName();
   }
 }
 public static CoreSession wrap(CoreSession session) {
   try {
     TransactionHelper.lookupTransactionManager();
   } catch (NamingException e) {
     // no transactions, do not wrap
     return session;
   }
   ClassLoader cl = session.getClass().getClassLoader();
   return (CoreSession)
       Proxy.newProxyInstance(cl, INTERFACES, new TransactionalCoreSessionWrapper(session));
 }
  /**
   * Calls the {@link #run()} method with an unrestricted {@link #session}. During this call, {@link
   * #isUnrestricted} is set to {@code true}.
   */
  public void runUnrestricted() {
    isUnrestricted = true;
    try {
      if (sessionIsAlreadyUnrestricted) {
        run();
        return;
      }

      LoginContext loginContext;
      try {
        loginContext = Framework.loginAs(originatingUsername);
      } catch (LoginException e) {
        throw new NuxeoException(e);
      }
      try {
        CoreSession baseSession = session;
        session = CoreInstance.openCoreSession(repositoryName);
        try {
          run();
        } finally {
          try {
            session.close();
          } finally {
            session = baseSession;
          }
        }
      } finally {
        try {
          // loginContext may be null in tests
          if (loginContext != null) {
            loginContext.logout();
          }
        } catch (LoginException e) {
          throw new NuxeoException(e);
        }
      }
    } finally {
      isUnrestricted = false;
    }
  }
 @Override
 public void afterCompletion(int status) {
   Transaction current = null;
   try {
     current = TransactionHelper.lookupTransactionManager().getTransaction();
   } catch (Exception e) {
     throw new Error("no tx", e);
   }
   Transaction main = threadBound.get();
   if (main.equals(current)) {
     threadBound.remove();
   }
   boolean committed;
   if (status == Status.STATUS_COMMITTED) {
     committed = true;
   } else if (status == Status.STATUS_ROLLEDBACK) {
     committed = false;
   } else {
     log.error("Unexpected status after completion: " + status);
     return;
   }
   session.afterCompletion(committed);
 }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Transaction main = threadBound.get();
    if (main == null) {
      // first call in thread
      try {
        main = TransactionHelper.lookupTransactionManager().getTransaction();

        if (main != null) {
          if (main.getStatus() != Status.STATUS_MARKED_ROLLBACK) {
            main.registerSynchronization(this);
            session.afterBegin();
            threadBound.set(main);
          }
        }
      } catch (NamingException e) {
        // no transaction manager, ignore
      } catch (Exception e) {
        log.error("Error on transaction synchronizer registration", e);
      }
      checkTxActiveRequired(method);
    }
    try {
      return method.invoke(session, args);
    } catch (Throwable t) {
      if (TransactionHelper.isTransactionActive() && needsRollback(method, t)) {
        TransactionHelper.setTransactionRollbackOnly();
      }
      if (t instanceof InvocationTargetException) {
        Throwable tt = ((InvocationTargetException) t).getTargetException();
        if (tt != null) {
          throw tt;
        }
      }
      throw t;
    }
  }
 @Override
 public void beforeCompletion() {
   session.beforeCompletion();
 }
 protected boolean isUnrestricted(CoreSession session) {
   return SecurityConstants.SYSTEM_USERNAME.equals(session.getPrincipal().getName())
       || (session.getPrincipal() instanceof NuxeoPrincipal
           && ((NuxeoPrincipal) session.getPrincipal()).isAdministrator());
 }