TypeAnalyzerState state) {
Class currentClass = state.getCurrentClass();
Class parent = currentClass.getSuperclass();
List newMethods = new LinkedList();
List newFields = new LinkedList();
AST ast = node.getAST();
CompilationUnit root = (CompilationUnit) node.getRoot();
List fieldNames = new LinkedList();
List fieldTypes = new LinkedList();
// Iterate over all the body declarations.
Iterator bodyIter = bodyDeclarations.iterator();
while (bodyIter.hasNext()) {
Object nextDeclaration = bodyIter.next();
// Handle only field declarations.
if (nextDeclaration instanceof FieldDeclaration) {
FieldDeclaration fieldDecl = (FieldDeclaration) nextDeclaration;
boolean isStatic = Modifier.isStatic(fieldDecl.getModifiers());
// If HANDLE_STATIC_FIELDS is set to false, do not refactor
// static fields.
if (isStatic && (HANDLE_STATIC_FIELDS != true)) {
continue;
}
// Handle only private fields or the $CHECKPOINT special field.
if (Modifier.isPrivate(fieldDecl.getModifiers())) {
Type type = Type.getType(fieldDecl);
// Iterate over all the fragments in the field declaration.
Iterator fragmentIter = fieldDecl.fragments().iterator();
while (fragmentIter.hasNext()) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragmentIter
.next();
String fieldName = fragment.getName().getIdentifier();
// Get the list of numbers of indices.
Hashtable[] tables = new Hashtable[] { _accessedFields,
_specialAccessedFields, _backupFields };
for (int i = 0; i < tables.length; i++) {
List indicesList = _getAccessedField(tables[i],
currentClass.getName(), fieldName);
if (indicesList == null) {
continue;
}
// Iterate over all the numbers of indices.
Iterator indicesIter = indicesList.iterator();
while (indicesIter.hasNext()) {
int indices = ((Integer) indicesIter.next())
.intValue();
// Create an extra method for every different
// number of indices.
if (tables[i] == _backupFields) {
newMethods.add(_createBackupMethod(ast,
root, state, fieldName, type,
indices, isStatic));
} else {
newMethods
.add(_createAssignMethod(
ast,
root,
state,
fieldName,
type,
indices,
tables[i] == _specialAccessedFields,
isStatic));
}
}
}
fieldNames.add(fieldName);
fieldTypes.add(type);
// Create a record field.
FieldDeclaration field = _createFieldRecord(ast, root,
state, fieldName, type.dimensions(), isStatic);
if (field != null) {
newFields.add(field);
}
}
}
}
}
boolean isInterface = node instanceof TypeDeclaration
&& ((TypeDeclaration) node).isInterface();
boolean isAnonymous = node instanceof AnonymousClassDeclaration;
if (isAnonymous) {
Class[] interfaces = currentClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (state.getCrossAnalyzedTypes().contains(
interfaces[i].getName())) {
isAnonymous = false;
}
}
}
RehandleDeclarationRecord declarationRecord = null;
if (isAnonymous) {
Class[] interfaces = currentClass.getInterfaces();
if (interfaces.length == 1) {
declarationRecord = new RehandleDeclarationRecord(
bodyDeclarations);
addToLists(_rehandleDeclaration, interfaces[0].getName(),
declarationRecord);
}
}
// Do not handle anonymous class declarations in a static method.
boolean ignore = !_isInStatic.isEmpty()
&& (_isInStatic.peek() == Boolean.TRUE) && isAnonymous;
// Add an array of all the records.
if (!isInterface && !ignore) {
newFields.add(_createRecordArray(ast, root, state, fieldNames));
}
// Add a commit method.
MethodDeclaration commitMethod = null;
if (!ignore) {
commitMethod = _createCommitMethod(ast, root, state, fieldNames,
fieldTypes, isAnonymous, isInterface);
newMethods.add(commitMethod);
}
if (declarationRecord != null) {
if (!ignore) {
declarationRecord._addExtendedDeclaration(commitMethod);
}
MethodDeclaration fixedCommitMethod = _createCommitMethod(ast,
root, state, fieldNames, fieldTypes, false, isInterface);
declarationRecord._addFixedDeclaration(fixedCommitMethod);
}
// Add a restore method.
MethodDeclaration restoreMethod = null;
if (!ignore) {
restoreMethod = _createRestoreMethod(ast, root, state, fieldNames,
fieldTypes, isAnonymous, isInterface);
newMethods.add(restoreMethod);
}
if (declarationRecord != null) {
if (!ignore) {
declarationRecord._addExtendedDeclaration(restoreMethod);
}
MethodDeclaration fixedRestoreMethod = _createRestoreMethod(ast,
root, state, fieldNames, fieldTypes, false, isInterface);
declarationRecord._addFixedDeclaration(fixedRestoreMethod);
}
// Get checkpoint method.
MethodDeclaration getCheckpoint = null;
if (!ignore) {
getCheckpoint = _createGetCheckpointMethod(ast, root, state,
isAnonymous, isInterface);
if (getCheckpoint != null) {
newMethods.add(getCheckpoint);
}
}
if (declarationRecord != null) {
if (!ignore) {
declarationRecord._addExtendedDeclaration(getCheckpoint);
}
MethodDeclaration fixedGetCheckpoint = _createGetCheckpointMethod(
ast, root, state, false, isInterface);
declarationRecord._addFixedDeclaration(fixedGetCheckpoint);
}
// Set checkpoint method.
MethodDeclaration setCheckpoint = null;
if (!ignore) {
setCheckpoint = _createSetCheckpointMethod(ast, root, state,
isAnonymous, isInterface);
if (setCheckpoint != null) {
newMethods.add(setCheckpoint);
}
}
if (declarationRecord != null) {
if (!ignore) {
declarationRecord._addExtendedDeclaration(setCheckpoint);
}
MethodDeclaration fixedSetCheckpoint = _createSetCheckpointMethod(
ast, root, state, false, isInterface);
declarationRecord._addFixedDeclaration(fixedSetCheckpoint);
}
// Add an interface.
if (!ignore) {
if (isAnonymous) {
TypeDeclaration proxy = _createProxyClass(ast, root, state);
bodyDeclarations.add(proxy);
if (declarationRecord != null) {
declarationRecord._addExtendedDeclaration(proxy);
}
} else {
// Set the class to implement Rollbackable.
if (node instanceof TypeDeclaration) {
String rollbackType = getClassName(Rollbackable.class,
state, root);
((TypeDeclaration) node).superInterfaceTypes().add(
ast.newSimpleType(createName(ast, rollbackType)));
}
if (!isInterface) {
// Create a checkpoint field.
FieldDeclaration checkpointField = _createCheckpointField(
ast, root, state);
if (checkpointField != null) {
bodyDeclarations.add(0, checkpointField);
}
// Create a record for the checkpoint field.
FieldDeclaration record = _createCheckpointRecord(ast,
root, state);
if (record != null) {
newFields.add(0, record);
}
}
}
}
// Add all the methods and then all the fields.
if (!ignore) {
bodyDeclarations.addAll(newMethods);
bodyDeclarations.addAll(newFields);
} else {
if (declarationRecord != null) {
declarationRecord._addFixedDeclarations(newMethods);
declarationRecord._addFixedDeclarations(newFields);
}
}
if (isAnonymous && !ignore) {
// Create a simple initializer.
Initializer initializer = ast.newInitializer();
Block body = ast.newBlock();
initializer.setBody(body);
MethodInvocation addInvocation = ast.newMethodInvocation();
addInvocation.setExpression(ast.newSimpleName(CHECKPOINT_NAME));
addInvocation.setName(ast.newSimpleName("addObject"));
ClassInstanceCreation proxy = ast.newClassInstanceCreation();
proxy
.setType(ast.newSimpleType(ast
.newSimpleName(_getProxyName())));
addInvocation.arguments().add(proxy);
body.statements().add(ast.newExpressionStatement(addInvocation));
bodyDeclarations.add(initializer);
if (declarationRecord != null) {
declarationRecord._addExtendedDeclaration(initializer);
}