package org.keycloak.services.resources;

import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.services.models.KeycloakSession;
import org.keycloak.services.models.KeycloakTransaction;

/**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @version $Revision: 1 $
 */
public class Transaction {
    protected KeycloakSession session;
    protected KeycloakTransaction transaction;
    protected boolean closeSession;

    public Transaction() {
        this(true);
    }

    public Transaction(boolean close) {
        this.session = ResteasyProviderFactory.getContextData(KeycloakSession.class);
        transaction = session.getTransaction();
        closeSession = close;

    }

    protected void runImpl() {

    }

    public void run() {
        boolean wasActive = transaction.isActive();
        if (!wasActive) transaction.begin();
        try {
            runImpl();
            if (!wasActive && transaction.isActive()) transaction.commit();
        } catch (RuntimeException e) {
            if (!wasActive && transaction.isActive()) transaction.rollback();
            throw e;
        } finally {
            if (!wasActive && closeSession) session.close();
        }
    }

    protected <T> T callImpl() {
        return null;
    }

    public <T> T call() {
        boolean wasActive = transaction.isActive();
        if (!wasActive) transaction.begin();
        try {
            T rtn = callImpl();
            if (!wasActive && transaction.isActive()) transaction.commit();
            return rtn;
        } catch (RuntimeException e) {
            if (!wasActive && transaction.isActive()) transaction.rollback();
            throw e;
        } finally {
            if (!wasActive && closeSession) session.close();
        }
    }
}

@@ -195,26 +195,184 @@
 loak
-Transaction;%0D%0A%0D%0A/*
+SessionFactory;%0D%0Aimport org.keycloak.services.models.KeycloakTransaction;%0D%0A%0D%0A/**%0D%0A * Meant to be used as an inner class wrapper (I forget the pattern name, its been awhile).%0D%0A 
 *%0D%0A 
@@ -632,322 +632,1023 @@
     
-public Transaction() %7B%0D%0A        this(true);%0D%0A    %7D%0D%0A%0D%0A    public Transaction(boolean close) %7B%0D%0A        this.session = ResteasyProviderFactory.getContextData(KeycloakSession.class);%0D%0A        transaction = session.getTransaction();%0D%0A        closeSession = close;%0D%0A%0D%0A    %7D%0D%0A%0D%0A    protected void runImpl() %7B%0D%0A%0D%0A    %7D%0D%0A
+/**%0D%0A     * Pull KeycloakSession from @Context%0D%0A     *%0D%0A     * Will close session after finished%0D%0A     *%0D%0A     */%0D%0A    public Transaction() %7B%0D%0A        this(true);%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     *  Pull KeycloakSession from @Context%0D%0A     *%0D%0A     * @param close whether to close the session or not after completion%0D%0A     */%0D%0A    public Transaction(boolean close) %7B%0D%0A        this.session = ResteasyProviderFactory.getContextData(KeycloakSession.class);%0D%0A        transaction = session.getTransaction();%0D%0A        closeSession = close;%0D%0A%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     * Creates and manages its own session.%0D%0A     *%0D%0A     * @param factory%0D%0A     */%0D%0A    public Transaction(KeycloakSessionFactory factory) %7B%0D%0A        this.closeSession = true;%0D%0A        this.session = factory.createSession();%0D%0A        this.transaction = session.getTransaction();%0D%0A    %7D%0D%0A%0D%0A    protected void runImpl() %7B%0D%0A%0D%0A    %7D%0D%0A%0D%0A    /**%0D%0A     * Will not begin or end a transaction or close a session if the transaction was already active when called%0D%0A     *%0D%0A     */
 %0D%0A  
@@ -2190,24 +2190,163 @@
 ;%0D%0A    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Will not begin or end a transaction or close a session if the transaction was already active when called%0D%0A     *%0D%0A     */%0D%0A
     public %3C

upgrade picketlink