package org.eclipse.jdt.internal.corext.codemanipulation.tostringgeneration;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTMatcher;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationMessages;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2Core;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
public class GenerateToStringOperation implements IWorkspaceRunnable {
private IJavaElement fInsert;
private CompilationUnitRewrite fRewrite;
private ToStringGenerationContext fContext;
private AbstractToStringGenerator fGenerator;
private CompilationUnit fUnit;
private boolean fApply= false;
private boolean fSave= false;
private TextEdit fEdit= null;
private GenerateToStringOperation(IJavaElement insert, ToStringGenerationContext context, AbstractToStringGenerator generator, CompilationUnit unit, CompilationUnitRewrite rewrite, boolean apply, boolean save) {
fInsert= insert;
fContext= context;
fRewrite= rewrite;
fUnit= unit;
fGenerator= generator;
fApply= apply;
fSave= save;
}
@Override
public void run(IProgressMonitor monitor) throws CoreException {
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask("", 1);
monitor.setTaskName(CodeGenerationMessages.GenerateToStringOperation_description);
AbstractTypeDeclaration declaration= (AbstractTypeDeclaration)ASTNodes.findDeclaration(fContext.getTypeBinding(), fRewrite.getRoot());
ListRewrite rewriter= fRewrite.getASTRewrite().getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
if (fContext.getTypeBinding() != null && rewriter != null) {
MethodDeclaration toStringMethod= fGenerator.generateToStringMethod();
List<BodyDeclaration> list= declaration.bodyDeclarations();
BodyDeclaration replace= findMethodToReplace(list, toStringMethod);
if (replace == null || ((Boolean)toStringMethod.getProperty(AbstractToStringGenerator.OVERWRITE_METHOD_PROPERTY)).booleanValue())
insertMethod(toStringMethod, rewriter, replace);
List<MethodDeclaration> helperMethods= fGenerator.generateHelperMethods();
for (Iterator<MethodDeclaration> iterator= helperMethods.iterator(); iterator.hasNext();) {
MethodDeclaration method= iterator.next();
replace= findMethodToReplace(list, method);
if (replace == null || ((Boolean)method.getProperty(AbstractToStringGenerator.OVERWRITE_METHOD_PROPERTY)).booleanValue()) {
insertMethod(method, rewriter, replace);
}
}
fEdit= fRewrite.createChange(true).getEdit();
if (fApply) {
JavaModelUtil.applyEdit((ICompilationUnit)fUnit.getJavaElement(), fEdit, fSave, monitor);
}
}
} finally {
monitor.done();
}
}
public final TextEdit getResultingEdit() {
return fEdit;
}
public RefactoringStatus checkConditions() {
return fGenerator.checkConditions();
}
protected void insertMethod(MethodDeclaration method, ListRewrite rewriter, BodyDeclaration replace) throws JavaModelException {
if (replace != null) {
rewriter.replace(replace, method, null);
} else {
ASTNode insertion= StubUtility2Core.getNodeToInsertBefore(rewriter, fInsert);
if (insertion != null)
rewriter.insertBefore(method, insertion, null);
else
rewriter.insertLast(method, null);
}
}
protected BodyDeclaration findMethodToReplace(final List<BodyDeclaration> list, MethodDeclaration method) {
for (final Iterator<BodyDeclaration> iterator= list.iterator(); iterator.hasNext();) {
final BodyDeclaration bodyDecl= iterator.next();
if (bodyDecl instanceof MethodDeclaration) {
final MethodDeclaration method2= (MethodDeclaration)bodyDecl;
if (method2.getName().getIdentifier().equals(method.getName().getIdentifier()) && method2.parameters().size() == method.parameters().size()) {
Iterator<SingleVariableDeclaration> iterator1= method.parameters().iterator();
Iterator<SingleVariableDeclaration> iterator2= method2.parameters().iterator();
boolean ok= true;
while (iterator1.hasNext()) {
if (!iterator1.next().getType().subtreeMatch(new ASTMatcher(), iterator2.next().getType())) {
ok= false;
break;
}
}
if (ok)
return method2;
}
}
}
return null;
}
public ISchedulingRule getSchedulingRule() {
return ResourcesPlugin.getWorkspace().getRoot();
}
public static final int STRING_CONCATENATION= 0;
public static final int STRING_BUILDER= 1;
public static final int STRING_BUILDER_CHAINED= 2;
public static final int STRING_FORMAT= 3;
public static final int CUSTOM_BUILDER= 4;
private final static String[] hardcoded_styles= {
CodeGenerationMessages.GenerateToStringOperation_stringConcatenation_style_name,
CodeGenerationMessages.GenerateToStringOperation_stringBuilder_style_name,
CodeGenerationMessages.GenerateToStringOperation_StringBuilder_chained_style_name,
CodeGenerationMessages.GenerateToStringOperation_string_format_style_name,
CodeGenerationMessages.GenerateToStringOperation_customStringBuilder_style_name
};
public static String[] getStyleNames() {
return hardcoded_styles;
}
private static AbstractToStringGenerator createToStringGenerator(int toStringStyle) {
switch (toStringStyle) {
case STRING_CONCATENATION:
return new StringConcatenationGenerator();
case STRING_BUILDER:
return new StringBuilderGenerator();
case STRING_BUILDER_CHAINED:
return new StringBuilderChainGenerator();
case STRING_FORMAT:
return new StringFormatGenerator();
case CUSTOM_BUILDER:
return new CustomBuilderGenerator();
default:
throw new IllegalArgumentException("Undefined toString() code style: " + toStringStyle);
}
}
public static ToStringTemplateParser createTemplateParser(int toStringStyle) {
return new ToStringTemplateParser();
}
public static GenerateToStringOperation createOperation(ITypeBinding typeBinding, Object[] selectedBindings, CompilationUnit unit, IJavaElement elementPosition,
ToStringGenerationSettingsCore settings, boolean apply, boolean save) {
AbstractToStringGenerator generator= createToStringGenerator(settings.toStringStyle);
ToStringTemplateParser parser= createTemplateParser(settings.toStringStyle);
parser.parseTemplate(settings.stringFormatTemplate);
CompilationUnitRewrite rewrite= new CompilationUnitRewrite((ICompilationUnit)unit.getTypeRoot(), unit);
ToStringGenerationContext context= new ToStringGenerationContext(parser, selectedBindings, settings, typeBinding, rewrite);
generator.setContext(context);
return new GenerateToStringOperation(elementPosition, context, generator, unit, rewrite, apply, save);
}
}