com.jpattern.core.command.CommandChain Maven / Gradle / Ivy
package com.jpattern.core.command;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import com.jpattern.core.IProvider;
import com.jpattern.shared.result.ErrorMessage;
import com.jpattern.shared.result.IErrorMessage;
/**
*
* @author Francesco Cina'
*
* 11/set/2011
*/
public final class CommandChain extends ICommand {
private List> commands = new ArrayList>();
private final ICommandChainStrategy chainStrategy;
private boolean executed = false;
private boolean rolledback = false;
public CommandChain() {
this(new ConditionalCommandChainStrategy());
}
public CommandChain(ICommandChainStrategy chainStrategy) {
this.chainStrategy = chainStrategy;
}
@Override
protected final void doExec(boolean catchRuntimeException, ACommandResult commandResult) {
executed = false;
rolledback = false;
CommandChainResult commandChainResult = new CommandChainResult(commandResult);
commandChainResult.setExecutionStart(this);
Iterator> commandsIterator = commands.iterator();
while (commandsIterator.hasNext() && chainStrategy.executeNext( commandChainResult )) {
ICommand super T> command = null;
try {
command = commandsIterator.next();
command.visit(getProvider());
commandChainResult.setExecutionStart(command);
chainStrategy.doExec(command, commandChainResult, catchRuntimeException, getCommandExecutor());
} catch (RuntimeException e) {
if (!catchRuntimeException) throw e;
getLogger().error("doExec", "RuntimeException thrown during command chain execution", e);
commandChainResult.addErrorMessage(new ErrorMessage(ICommandErrorsCostants.RUNTIME_EXEC_ERROR_NAME, e.getMessage()));
}
}
executed = true;
checkIfRollback(catchRuntimeException, commandChainResult);
commandChainResult.setExecutionEnd(this);
}
@Override
protected final void doRollback(boolean catchRuntimeException, ACommandResult commandResult) {
if (executed && !rolledback) {
CommandChainResult commandChainResult = new CommandChainResult(commandResult);
commandChainResult.setExecutionStart(this);
for (int i = (commands.size()-1); i>=0 ; i--) {
ICommand super T> command = null;
try {
command = commands.get(i);
command.visit(getProvider());
commandChainResult.setExecutionStart(command);
chainStrategy.doRollback(command, commandChainResult, catchRuntimeException, getCommandExecutor());
} catch (RuntimeException e) {
if (!catchRuntimeException) throw e;
getLogger().error("doRollback", "RuntimeException thrown during command chain rollback", e);
commandChainResult.addErrorMessage(new ErrorMessage(ICommandErrorsCostants.RUNTIME_ROLLBACK_ERROR_NAME, e.getMessage()));
}
}
rolledback = true;
commandChainResult.setExecutionEnd(this);
}
}
private final void checkIfRollback(boolean catchRuntimeException, ACommandResult commandResult) {
if (!commandResult.getErrorMessages().isEmpty() && chainStrategy.executeRollback()) {
for (int i = (commands.size()-1); i>=0 ; i--) {
commands.get(i).doRollback(catchRuntimeException, commandResult);
}
rolledback = true;
}
}
public final void addCommand(ICommand super T> command) {
commands.add(command);
}
private class CommandChainResult extends ACommandResult {
private static final long serialVersionUID = 1L;
private final ACommandResult commandResult;
private List> commandInExecutionList = new Vector>();
CommandChainResult(ACommandResult commandResult) {
this.commandResult = commandResult;
}
@Override
public synchronized void addErrorMessage(IErrorMessage errorMessage) {
commandResult.addErrorMessage(errorMessage);
}
@Override
public synchronized String asString() {
return commandResult.asString();
}
@Override
public synchronized List getErrorMessages() {
return commandResult.getErrorMessages();
}
@Override
public synchronized boolean isValid() {
return commandResult.isValid();
}
@Override
public synchronized boolean isExecutionEnd() {
return commandInExecutionList.isEmpty();
}
@Override
public synchronized void waitExecutionEnd() throws InterruptedException {
commandResult.waitExecutionEnd();
}
@Override
protected synchronized void setExecutionEnd(ICommand> command) {
commandInExecutionList.remove(command);
if (isExecutionEnd()) {
commandResult.setExecutionEnd(CommandChain.this);
}
}
protected final synchronized void setExecutionStart(ICommand> command) {
commandInExecutionList.add(command);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy