/******************************************************************************* * 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.jdt.proposals; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.MemberValuePair; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition; import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; import org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposal; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.viewers.StyledString; import org.eclipse.swt.widgets.Display; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.TextEdit; import org.springframework.ide.eclipse.quickfix.jdt.processors.JdtQuickfixUtils; import org.springframework.ide.eclipse.quickfix.jdt.processors.RequestMappingDialog; import org.springframework.ide.eclipse.quickfix.jdt.processors.RequestMappingDialog.Method; /** * @author Terry Denney */ public class AddRequestMappingCompletionProposal extends JavaTypeCompletionProposal { private static final String REQUEST_MAPPING_IMPORT = "org.springframework.web.bind.annotation.RequestMapping"; private static final String REQUEST_METHOD_IMPORT = "org.springframework.web.bind.annotation.RequestMethod"; private final ICompilationUnit cu; private final BodyDeclaration decl; public AddRequestMappingCompletionProposal(String typeName, BodyDeclaration decl, ICompilationUnit cu, int start, int length, int relevance) { super("", cu, start, length, null, getDisplayName(typeName), relevance); this.decl = decl; this.cu = cu; } @Override public void apply(IDocument document, char trigger, int offset) { applyChange(document, offset); // super.apply(document, trigger, offset); } @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { applyChange(viewer.getDocument(), offset); // super.apply(viewer, trigger, stateMask, offset); } private void applyChange(IDocument document, int offset) { try { if (decl instanceof MethodDeclaration) { applyChangeForMethod(document, offset); } else if (decl instanceof TypeDeclaration) { applyChangeForType(document, offset); } } catch (MalformedTreeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JavaModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void applyChangeForMethod(IDocument document, int offset) throws MalformedTreeException, JavaModelException, IllegalArgumentException, BadLocationException { MultiTextEdit edit = new MultiTextEdit(); String methodTypeString = null; RequestMappingDialog dialog = new RequestMappingDialog(Display.getDefault().getActiveShell()); if (dialog.open() == Dialog.OK) { TextEdit importEdit = JdtQuickfixUtils.getTextEditForImport(cu, REQUEST_MAPPING_IMPORT); if (importEdit != null) { edit.addChild(importEdit); } Method methodType = dialog.getMethodType(); if (methodType == Method.GET) { methodTypeString = "GET"; } else if (methodType == Method.POST) { methodTypeString = "POST"; } ASTRewrite astRewrite = ASTRewrite.create(decl.getAST()); NormalAnnotation annotation = astRewrite.getAST().newNormalAnnotation(); annotation.setTypeName(astRewrite.getAST().newSimpleName("RequestMapping")); //$NON-NLS-1$ if (methodTypeString != null) { importEdit = JdtQuickfixUtils.getTextEditForImport(cu, REQUEST_METHOD_IMPORT); if (importEdit != null) { edit.addChild(importEdit); } ListRewrite listRewrite = astRewrite.getListRewrite(annotation, NormalAnnotation.VALUES_PROPERTY); AST annotationAST = annotation.getAST(); MemberValuePair pair = annotationAST.newMemberValuePair(); pair.setName(annotationAST.newSimpleName("method")); QualifiedName valueName = annotationAST.newQualifiedName(annotationAST.newSimpleName("RequestMethod"), annotationAST.newSimpleName(methodTypeString)); pair.setValue(valueName); listRewrite.insertFirst(pair, null); } astRewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(annotation, null); edit.addChild(astRewrite.rewriteAST()); int oldLength = document.getLength(); // int oldCurserPos = document.getCursorPosition(); edit.apply(document); int diff = document.getLength() - oldLength; setCursorPosition(diff + offset); } } private void applyChangeForType(IDocument document, int offset) throws MalformedTreeException, JavaModelException, IllegalArgumentException, BadLocationException { MultiTextEdit edit = new MultiTextEdit(); TextEdit importEdit = JdtQuickfixUtils.getTextEditForImport(cu, REQUEST_MAPPING_IMPORT); if (importEdit != null) { edit.addChild(importEdit); } ASTRewrite astRewrite = ASTRewrite.create(decl.getAST()); NormalAnnotation annotation = astRewrite.getAST().newNormalAnnotation(); annotation.setTypeName(astRewrite.getAST().newSimpleName("RequestMapping")); astRewrite.getListRewrite(decl, TypeDeclaration.MODIFIERS2_PROPERTY).insertFirst(annotation, null); ITrackedNodePosition tracker = astRewrite.track(annotation.getTypeName()); edit.addChild(astRewrite.rewriteAST()); edit.apply(document); setReplacementOffset(tracker.getStartPosition() + annotation.getTypeName().getFullyQualifiedName().length() + 1); } @Override protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException { applyChange(document, offset); return true; } private static StyledString getDisplayName(String typeName) { StyledString buf = new StyledString(); buf.append("Add @RequestMapping annotation for '"); buf.append(typeName); buf.append("'"); return buf; } }