/*******************************************************************************
* Copyright (c) 2007, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ext.java.jdt.internal.corext.fix;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.api.IProblemLocation;
import org.eclipse.che.ide.ext.java.jdt.core.JavaCore;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AST;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTNode;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit;
import org.eclipse.che.ide.ext.java.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Modifier;
import org.eclipse.che.ide.ext.java.jdt.core.dom.TypeDeclaration;
import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.refactoring.code.CompilationUnitChange;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.CorrectionMessages;
import org.eclipse.che.ide.ext.java.jdt.refactoring.Change;
import org.eclipse.che.ide.ext.java.jdt.refactoring.NullChange;
import org.eclipse.che.ide.ext.java.jdt.text.Document;
import org.eclipse.che.ide.ext.java.jdt.text.edits.MultiTextEdit;
import org.eclipse.che.ide.ext.java.jdt.text.edits.TextEditGroup;
import org.eclipse.che.ide.runtime.Assert;
import org.eclipse.che.ide.runtime.CoreException;
import org.eclipse.che.ide.runtime.IStatus;
import org.eclipse.che.ide.runtime.Status;
import java.util.ArrayList;
public class UnimplementedCodeFix extends CompilationUnitRewriteOperationsFix {
public static final class MakeTypeAbstractOperation extends CompilationUnitRewriteOperation {
private final TypeDeclaration fTypeDeclaration;
public MakeTypeAbstractOperation(TypeDeclaration typeDeclaration) {
fTypeDeclaration = typeDeclaration;
}
/** {@inheritDoc} */
@Override
public void rewriteAST(CompilationUnitRewrite cuRewrite) throws CoreException {
AST ast = cuRewrite.getAST();
ASTRewrite rewrite = cuRewrite.getASTRewrite();
Modifier newModifier = ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
TextEditGroup textEditGroup =
createTextEditGroup(CorrectionMessages.INSTANCE.UnimplementedCodeFix_TextEditGroup_label(), cuRewrite);
rewrite.getListRewrite(fTypeDeclaration, TypeDeclaration.MODIFIERS2_PROPERTY).insertLast(newModifier,
textEditGroup);
//TODO
// LinkedProposalPositionGroup group = new LinkedProposalPositionGroup("modifier"); //$NON-NLS-1$
// group.addPosition(rewrite.track(newModifier), !linkedProposalPositions.hasLinkedPositions());
// linkedProposalPositions.addPositionGroup(group);
}
}
public static ICleanUpFix createCleanUp(CompilationUnit root, boolean addMissingMethod, boolean makeTypeAbstract,
IProblemLocation[] problems, Document document) {
Assert.isLegal(!addMissingMethod || !makeTypeAbstract);
if (!addMissingMethod && !makeTypeAbstract)
return null;
if (problems.length == 0)
return null;
ArrayList<CompilationUnitRewriteOperation> operations = new ArrayList<CompilationUnitRewriteOperation>();
for (int i = 0; i < problems.length; i++) {
IProblemLocation problem = problems[i];
if (addMissingMethod) {
ASTNode typeNode = getSelectedTypeNode(root, problem);
if (typeNode != null && !isTypeBindingNull(typeNode)) {
operations.add(new AddUnimplementedMethodsOperation(typeNode));
}
} else {
ASTNode typeNode = getSelectedTypeNode(root, problem);
if (typeNode instanceof TypeDeclaration) {
operations.add(new MakeTypeAbstractOperation((TypeDeclaration)typeNode));
}
}
}
if (operations.size() == 0)
return null;
String label;
if (addMissingMethod) {
label = CorrectionMessages.INSTANCE.UnimplementedMethodsCorrectionProposal_description();
} else {
label = CorrectionMessages.INSTANCE.UnimplementedCodeFix_MakeAbstractFix_label();
}
return new UnimplementedCodeFix(label, root, operations.toArray(new CompilationUnitRewriteOperation[operations
.size()]), document);
}
public static IProposableFix createAddUnimplementedMethodsFix(final CompilationUnit root, IProblemLocation problem,
final Document document) {
ASTNode typeNode = getSelectedTypeNode(root, problem);
if (typeNode == null)
return null;
if (isTypeBindingNull(typeNode))
return null;
AddUnimplementedMethodsOperation operation = new AddUnimplementedMethodsOperation(typeNode);
if (operation.getMethodsToImplement().length > 0) {
return new UnimplementedCodeFix(
CorrectionMessages.INSTANCE.UnimplementedMethodsCorrectionProposal_description(), root,
new CompilationUnitRewriteOperation[]{operation}, document);
} else {
return new IProposableFix() {
public CompilationUnitChange createChange() throws CoreException {
CompilationUnitChange change =
new CompilationUnitChange(
CorrectionMessages.INSTANCE.UnimplementedMethodsCorrectionProposal_description(), document) {
@Override
public Change perform() throws CoreException {
//TODO
// Shell shell= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
// String dialogTitle= CorrectionMessages.UnimplementedMethodsCorrectionProposal_description;
// IStatus status= getStatus();
// ErrorDialog.openError(shell, dialogTitle,
// CorrectionMessages.UnimplementedCodeFix_DependenciesErrorMessage, status);
return new NullChange();
}
};
change.setEdit(new MultiTextEdit());
return change;
}
public String getAdditionalProposalInfo() {
return new String();
}
public String getDisplayString() {
return CorrectionMessages.INSTANCE.UnimplementedMethodsCorrectionProposal_description();
}
public IStatus getStatus() {
return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID,
CorrectionMessages.INSTANCE.UnimplementedCodeFix_DependenciesStatusMessage());
}
};
}
}
public static UnimplementedCodeFix createMakeTypeAbstractFix(CompilationUnit root, IProblemLocation problem,
Document document) {
ASTNode typeNode = getSelectedTypeNode(root, problem);
if (!(typeNode instanceof TypeDeclaration))
return null;
TypeDeclaration typeDeclaration = (TypeDeclaration)typeNode;
MakeTypeAbstractOperation operation = new MakeTypeAbstractOperation(typeDeclaration);
//TODO
String label =
CorrectionMessages.INSTANCE.ModifierCorrectionSubProcessor_addabstract_description(typeDeclaration.getName()
.getIdentifier());
// CorrectionMessages.INSTANCE.ModifierCorrectionSubProcessor_addabstract_description(
// BasicElementLabels.getJavaElementName(typeDeclaration.getName().getIdentifier()));
return new UnimplementedCodeFix(label, root, new CompilationUnitRewriteOperation[]{operation}, document);
}
public static ASTNode getSelectedTypeNode(CompilationUnit root, IProblemLocation problem) {
ASTNode selectedNode = problem.getCoveringNode(root);
if (selectedNode == null)
return null;
if (selectedNode.getNodeType() == ASTNode.ANONYMOUS_CLASS_DECLARATION) { // bug 200016
selectedNode = selectedNode.getParent();
}
if (selectedNode.getLocationInParent() == EnumConstantDeclaration.NAME_PROPERTY) {
selectedNode = selectedNode.getParent();
}
if (selectedNode.getNodeType() == ASTNode.SIMPLE_NAME
&& selectedNode.getParent() instanceof AbstractTypeDeclaration) {
return selectedNode.getParent();
} else if (selectedNode.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) {
return ((ClassInstanceCreation)selectedNode).getAnonymousClassDeclaration();
} else if (selectedNode.getNodeType() == ASTNode.ENUM_CONSTANT_DECLARATION) {
EnumConstantDeclaration enumConst = (EnumConstantDeclaration)selectedNode;
if (enumConst.getAnonymousClassDeclaration() != null)
return enumConst.getAnonymousClassDeclaration();
return enumConst;
} else {
return null;
}
}
private static boolean isTypeBindingNull(ASTNode typeNode) {
if (typeNode instanceof AbstractTypeDeclaration) {
AbstractTypeDeclaration abstractTypeDeclaration = (AbstractTypeDeclaration)typeNode;
if (abstractTypeDeclaration.resolveBinding() == null)
return true;
return false;
} else if (typeNode instanceof AnonymousClassDeclaration) {
AnonymousClassDeclaration anonymousClassDeclaration = (AnonymousClassDeclaration)typeNode;
if (anonymousClassDeclaration.resolveBinding() == null)
return true;
return false;
} else if (typeNode instanceof EnumConstantDeclaration) {
return false;
} else {
return true;
}
}
public UnimplementedCodeFix(String name, CompilationUnit compilationUnit,
CompilationUnitRewriteOperation[] fixRewriteOperations, Document document) {
super(name, compilationUnit, fixRewriteOperations, document);
}
}