package io.ebeaninternal.api;
import io.ebean.TxScope;
import java.util.ArrayList;
public class ScopeTrans {
private static final int OPCODE_ATHROW = 191;
private final SpiTransaction transaction;
private final boolean rollbackOnChecked;
private final boolean created;
private final ArrayList<Class<? extends Throwable>> noRollbackFor;
private final ArrayList<Class<? extends Throwable>> rollbackFor;
private Boolean restoreBatch;
private Boolean restoreBatchOnCascade;
private int restoreBatchSize;
private Boolean restoreBatchGeneratedKeys;
private boolean restoreBatchFlushOnQuery;
private boolean rolledBack;
private boolean nestedCommit;
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
this.rollbackOnChecked = rollbackOnChecked;
this.created = created;
this.transaction = transaction;
this.noRollbackFor = txScope.getNoRollbackFor();
this.rollbackFor = txScope.getRollbackFor();
if (transaction != null) {
if (!created && txScope.isBatchSet() || txScope.isBatchOnCascadeSet() || txScope.isBatchSizeSet()) {
restoreBatch = transaction.isBatchMode();
restoreBatchOnCascade = transaction.isBatchOnCascade();
restoreBatchSize = transaction.getBatchSize();
restoreBatchGeneratedKeys = transaction.getBatchGetGeneratedKeys();
restoreBatchFlushOnQuery = transaction.isFlushOnQuery();
}
if (txScope.isBatchSet()) {
transaction.setBatchMode(txScope.isBatchMode());
}
if (!txScope.isFlushOnQuery()) {
transaction.setFlushOnQuery(false);
}
if (txScope.isBatchOnCascadeSet()) {
transaction.setBatchOnCascade(txScope.isBatchOnCascade());
}
if (txScope.isBatchSizeSet()) {
transaction.setBatchSize(txScope.getBatchSize());
}
if (txScope.isSkipGeneratedKeys()) {
transaction.setGetGeneratedKeys(false);
}
}
}
@Override
public String toString() {
return "ScopeTrans[" + transaction + "]";
}
protected SpiTransaction getTransaction() {
return transaction;
}
void complete(Object returnOrThrowable, int opCode) {
if (opCode == OPCODE_ATHROW) {
caughtThrowable((Throwable) returnOrThrowable);
}
complete();
}
public void complete() {
if (!rolledBack) {
commitTransaction();
}
}
public void end() {
if (created || !nestedCommit) {
transaction.end();
}
}
protected void commitTransaction() {
if (created) {
transaction.commit();
} else {
nestedCommit = true;
transaction.setFlushOnQuery(restoreBatchFlushOnQuery);
if (restoreBatch != null) {
transaction.setBatchMode(restoreBatch);
}
if (restoreBatchOnCascade != null) {
transaction.setBatchOnCascade(restoreBatchOnCascade);
}
if (restoreBatchSize > 0) {
transaction.setBatchSize(restoreBatchSize);
}
if (restoreBatchGeneratedKeys != null) {
transaction.setGetGeneratedKeys(restoreBatchGeneratedKeys);
}
}
}
public Error caughtError(Error e) {
rollback(e);
return e;
}
public void setRollbackOnly() {
if (transaction != null) {
transaction.setRollbackOnly();
}
}
public <T extends Throwable> T caughtThrowable(T e) {
if (isRollbackThrowable(e)) {
rollback(e);
}
return e;
}
protected void rollback(Throwable e) {
if (transaction != null && transaction.isActive()) {
transaction.rollback(e);
}
rolledBack = true;
}
private boolean isRollbackThrowable(Throwable e) {
if (e instanceof Error) {
return true;
}
if (noRollbackFor != null) {
for (Class<? extends Throwable> aNoRollbackFor : noRollbackFor) {
if (aNoRollbackFor.equals(e.getClass())) {
return false;
}
}
}
if (rollbackFor != null) {
for (Class<? extends Throwable> aRollbackFor : rollbackFor) {
if (aRollbackFor.equals(e.getClass())) {
return true;
}
}
}
return e instanceof RuntimeException || rollbackOnChecked;
}
}