/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * 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: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.quickfix.proposals; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.List; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.JavaPluginImages; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorPart; import org.eclipse.wst.sse.ui.StructuredTextEditor; import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart; import org.springframework.ide.eclipse.config.core.IConfigEditor; import org.springframework.ide.eclipse.quickfix.QuickfixUtils; /** * @author Terry Denney * @author Martin Lippert */ public class RemoveDeprecatedQuickFixProposal extends BeanAttributeQuickFixProposal implements ICompletionProposal { private IMethod method; private final String className; private String methodName; private final ICompilationUnit cu; public RemoveDeprecatedQuickFixProposal(int offset, int length, boolean missingEndQuote, String className, IType type) { super(offset, length, missingEndQuote); this.className = className; this.cu = type.getCompilationUnit(); } public RemoveDeprecatedQuickFixProposal(int offset, int length, boolean missingEndQuote, String className, String methodName, IMethod method) { super(offset, length, missingEndQuote); this.className = className; this.methodName = methodName; this.method = method; this.cu = method.getCompilationUnit(); } @Override public void applyQuickFix(IDocument document) { BodyDeclaration decl = getDeclaration(); removeDeprecatedAnnotation(document, cu, decl); } // copied from // org.eclipse.jdt.internal.ui.text.correction.ModifierCorrectionSubProcessor @SuppressWarnings("rawtypes") private Annotation findAnnotation(List modifiers) { for (int i = 0; i < modifiers.size(); i++) { Object curr = modifiers.get(i); if (curr instanceof Annotation) { Annotation annot = (Annotation) curr; ITypeBinding binding = annot.getTypeName().resolveTypeBinding(); if (binding != null && "java.lang.Deprecated".equals(binding.getQualifiedName())) { return annot; } } } return null; } private BodyDeclaration getDeclaration() { if (method != null) { return QuickfixUtils.getMethodDecl(method); } return QuickfixUtils.getTypeDecl(className, cu); } public String getDisplayString() { StringBuilder displayBuilder = new StringBuilder("Remove '@Deprecated' from "); displayBuilder.append(className); if (methodName != null) { displayBuilder.append("."); displayBuilder.append(methodName); displayBuilder.append("(..)"); } return displayBuilder.toString(); } public Image getImage() { return JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); } private ITextViewer getViewer(IEditorPart editorPart) { if (editorPart instanceof IConfigEditor) { IConfigEditor configEditor = (IConfigEditor) editorPart; return configEditor.getTextViewer(); } if (editorPart instanceof StructuredTextEditor) { return ((StructuredTextEditor) editorPart).getTextViewer(); } if (editorPart instanceof XMLMultiPageEditorPart) { Object result = QuickfixReflectionUtils.callProtectedMethod(editorPart, "getTextEditor"); return getViewer((IEditorPart) result); } if (editorPart instanceof JavaEditor) { return ((JavaEditor) editorPart).getViewer(); } return null; } // similar to // org.eclipse.jdt.internal.ui.text.correction.ModifierCorrectionSubProcessor.removeOverrideAnnotationProposal(..) public void removeDeprecatedAnnotation(IDocument document, ICompilationUnit cu, BodyDeclaration decl) { Annotation annot = findAnnotation(decl.modifiers()); if (annot != null) { ASTRewrite rewrite = ASTRewrite.create(annot.getAST()); rewrite.remove(annot, null); callASTRewriteCorrectionProposal(getDisplayString(), cu, rewrite, 6, getImage(), document); ITextViewer viewer = getViewer(JavaPlugin.getActivePage().getActiveEditor()); ITrackedNodePosition trackPos = rewrite.track(decl); if (trackPos != null && viewer != null) { viewer.setSelectedRange(trackPos.getStartPosition(), 0); } } } private void callASTRewriteCorrectionProposal(String displayString, ICompilationUnit cu2, ASTRewrite rewrite, int i, Image image, IDocument document) { try { Class<?> astRewriteClass = getASTRewriteCorrectionProposalClass(); Constructor<?> constructor = astRewriteClass.getConstructor(String.class, ICompilationUnit.class, ASTRewrite.class, int.class, Image.class); Object astRewriteCorrectionProposal = constructor.newInstance(displayString, cu2, rewrite, i, image); Method applyMethod = astRewriteCorrectionProposal.getClass().getMethod("apply", IDocument.class); applyMethod.invoke(astRewriteCorrectionProposal, document); } catch (Exception e) { e.printStackTrace(); } } private Class<?> getASTRewriteCorrectionProposalClass() throws ClassNotFoundException { try { // Eclipse 3.7 and previous versions return this.getClass().getClassLoader() .loadClass("org.eclipse.jdt.internal.ui.text.correction.proposals.ASTRewriteCorrectionProposal"); } catch (ClassNotFoundException e) { // Eclipse 3.8, 4.2 and beyond return this.getClass().getClassLoader() .loadClass("org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal"); } } }