method.parameters().add(trim);
// Return type default to "void".
if (!isInterface) {
// The method body.
Block body = ast.newBlock();
method.setBody(body);
// Create a restore statement for each managed field.
Iterator namesIter = fieldNames.iterator();
Iterator typesIter = fieldTypes.iterator();
while (namesIter.hasNext()) {
String fieldName = (String) namesIter.next();
Type fieldType = (Type) typesIter.next();
MethodInvocation restoreMethodCall = ast.newMethodInvocation();
restoreMethodCall.setExpression(ast
.newSimpleName(_getRecordName(fieldName)));
// Set the restore method name.
restoreMethodCall.arguments().add(ast.newSimpleName(fieldName));
restoreMethodCall.setName(ast.newSimpleName("restore"));
// Add two arguments to the restore method call.
restoreMethodCall.arguments().add(
ast.newSimpleName("timestamp"));
restoreMethodCall.arguments().add(ast.newSimpleName("trim"));
boolean isFinal = false;
try {
Field field = currentClass.getDeclaredField(fieldName);
if (java.lang.reflect.Modifier
.isFinal(field.getModifiers())) {
isFinal = true;
}
} catch (NoSuchFieldException e) {
}
if (isFinal) {
if ((_getAccessedField(currentClass.getName(), fieldName) != null)
|| !Type.isPrimitive(Type.getElementType(fieldType
.getName()))) {
body.statements().add(
ast.newExpressionStatement(restoreMethodCall));
}
} else {
Expression rightHandSide;
if (fieldType.isPrimitive()) {
rightHandSide = restoreMethodCall;
} else {
CastExpression castExpression = ast.newCastExpression();
String typeName = getClassName(fieldType.getName(),
state, root);
castExpression.setType(createType(ast, typeName));
castExpression.setExpression(restoreMethodCall);
rightHandSide = castExpression;
}
Assignment assignment = ast.newAssignment();
assignment.setLeftHandSide(ast.newSimpleName(fieldName));
assignment.setRightHandSide(rightHandSide);
body.statements().add(
ast.newExpressionStatement(assignment));
}
}
// Add a call to the restore method in the superclass, if necessary.
SuperMethodInvocation superRestore = ast.newSuperMethodInvocation();
superRestore.setName(ast
.newSimpleName(_getRestoreMethodName(false)));
superRestore.arguments().add(ast.newSimpleName("timestamp"));
superRestore.arguments().add(ast.newSimpleName("trim"));
Statement superRestoreStatement = ast
.newExpressionStatement(superRestore);
if ((parent != null)
&& (state.getCrossAnalyzedTypes()
.contains(parent.getName()) || hasMethod(parent,
methodName,
new Class[] { int.class, boolean.class }))) {
body.statements().add(superRestoreStatement);
} else {
// Restore the previous checkpoint, if necessary.
IfStatement restoreCheckpoint = ast.newIfStatement();
InfixExpression timestampTester = ast.newInfixExpression();
timestampTester.setLeftOperand(ast.newSimpleName("timestamp"));
timestampTester
.setOperator(InfixExpression.Operator.LESS_EQUALS);
MethodInvocation topTimestamp = ast.newMethodInvocation();
topTimestamp.setExpression(ast
.newSimpleName(CHECKPOINT_RECORD_NAME));
topTimestamp.setName(ast.newSimpleName("getTopTimestamp"));
timestampTester.setRightOperand(topTimestamp);
restoreCheckpoint.setExpression(timestampTester);
Block restoreBlock = ast.newBlock();
restoreCheckpoint.setThenStatement(restoreBlock);
// Assign the old checkpoint.
Assignment assignCheckpoint = ast.newAssignment();
assignCheckpoint.setLeftHandSide(ast
.newSimpleName(CHECKPOINT_NAME));
MethodInvocation restoreCheckpointInvocation = ast
.newMethodInvocation();
restoreCheckpointInvocation.setExpression(ast
.newSimpleName(CHECKPOINT_RECORD_NAME));
restoreCheckpointInvocation.setName(ast
.newSimpleName("restore"));
restoreCheckpointInvocation.arguments().add(
ast.newSimpleName(CHECKPOINT_NAME));
restoreCheckpointInvocation.arguments().add(
_createRollbackableObject(ast, isAnonymous));
restoreCheckpointInvocation.arguments().add(
ast.newSimpleName("timestamp"));
restoreCheckpointInvocation.arguments().add(
ast.newSimpleName("trim"));
assignCheckpoint.setRightHandSide(restoreCheckpointInvocation);
restoreBlock.statements().add(
ast.newExpressionStatement(assignCheckpoint));
// Pop the old states.
MethodInvocation popStates = ast.newMethodInvocation();
String recordType = getClassName(FieldRecord.class, state, root);
popStates.setExpression(createName(ast, recordType));
popStates.setName(ast.newSimpleName("popState"));
popStates.arguments().add(ast.newSimpleName(RECORDS_NAME));
restoreBlock.statements().add(
ast.newExpressionStatement(popStates));
// Recall the restore method.
MethodInvocation recursion = ast.newMethodInvocation();
recursion.setName(ast.newSimpleName(methodName));
recursion.arguments().add(ast.newSimpleName("timestamp"));
recursion.arguments().add(ast.newSimpleName("trim"));
restoreBlock.statements().add(
ast.newExpressionStatement(recursion));
body.statements().add(restoreCheckpoint);
if (parent != null) {