Package org.springframework.ide.eclipse.quickfix.jdt.proposals

Source Code of org.springframework.ide.eclipse.quickfix.jdt.proposals.AddAutowiredConstructorCompletionProposal

/*******************************************************************************
*  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.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
import org.eclipse.osgi.util.NLS;
import org.springframework.ide.eclipse.quickfix.QuickfixImages;


/**
* @author Kaitlin Duck Sherwood
* @since 2.9
*/
public class AddAutowiredConstructorCompletionProposal extends AnnotationCompletionProposal {

  private final TypeDeclaration typeDecl;

  private final ICompilationUnit compilationUnit;

  private final IVariableBinding[] variableBindings;

  public AddAutowiredConstructorCompletionProposal(TypeDeclaration typeDecl, ICompilationUnit cu,
      IVariableBinding[] myVariables) {
    super(NLS.bind("Add {0} constructor", "@Autowired"), cu, QuickfixImages.getImage(QuickfixImages.ANNOTATION));
    this.typeDecl = typeDecl;
    this.compilationUnit = cu;
    this.variableBindings = myVariables;
  }

  @Override
  protected ASTRewrite getRewrite() throws CoreException {

    CompilationUnit astRoot = ASTResolving.findParentCompilationUnit(typeDecl);
    AST ast = astRoot.getAST();
    ASTRewrite astRewrite = ASTRewrite.create(ast);
    ImportRewrite importRewrite = StubUtility.createImportRewrite(astRoot, true);
    ListRewrite listRewriter = astRewrite.getListRewrite(typeDecl, (typeDecl).getBodyDeclarationsProperty());

    if (listRewriter != null) {
      IJavaProject javaProject = compilationUnit.getJavaProject();
      CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(javaProject);
      MethodDeclaration methodDecl = createNewConstructor(typeDecl, ast);
      IMethodBinding constructorBinding = ASTNodes.getMethodBinding(methodDecl.getName());
      ITypeBinding typeBinding = ASTNodes.getTypeBinding(typeDecl.getName());
      ImportRewriteContext context = new ContextSensitiveImportRewriteContext(typeDecl, importRewrite);

      MethodDeclaration stub = StubUtility2.createConstructorStub(compilationUnit, astRewrite, importRewrite,
          context, typeBinding, constructorBinding, this.variableBindings, Modifier.PUBLIC, settings);
      if (stub != null) {

        IType type = null;
        // Getting the IType in question turned out to be much more
        // difficult than one would hope. At this point, it appears that
        // typeDecl "belongs to" a different compilation unit than the
        // one which we can get at from here. Thus, we have to look
        // through *this* compilation unit for the IType with the name
        // we are looking for.
        for (Object type2 : compilationUnit.getAllTypes()) {
          if (type2 instanceof IType) {

            // Allegedly, getFullyQualifiedName will return the
            // fully qualified name (e.g. a.b.c.Foo), but I have
            // seen it return a name without the package type.
            String typeName = typeDecl.getName().getFullyQualifiedName();
            String type2Name = ((IType) type2).getFullyQualifiedName();
            if (type2Name.endsWith(typeName)) {
              type = (IType) type2;
              break;
            }
          }
        }
        if (type == null) {
          return astRewrite; // this should never get hit
        }

        IJavaElement[] fields = type.getChildren();
        IJavaElement firstField;
        if (fields.length == 0) {
          firstField = null;
        }
        else {
          firstField = fields[0];
        }

        ASTNode insertion = StubUtility2.getNodeToInsertBefore(listRewriter, firstField);

        if (insertion != null && insertion.getParent() == typeDecl) {
          listRewriter.insertBefore(stub, insertion, null);
        }
        else {
          listRewriter.insertLast(stub, null);
        }

        constructorBinding = ASTNodes.getMethodBinding(stub.getName());
        addAutowiredAnnotation(javaProject, astRewrite, stub, constructorBinding);

      }
    }

    return astRewrite;
  }

  // based on StubUtility2.addOverrideAnnotation
  public void addAutowiredAnnotation(IJavaProject project, ASTRewrite rewrite, MethodDeclaration decl,
      IMethodBinding binding) {
    final Annotation marker = rewrite.getAST().newMarkerAnnotation();
    marker.setTypeName(rewrite.getAST().newSimpleName("Autowired")); //$NON-NLS-1$
    rewrite.getListRewrite(decl, MethodDeclaration.MODIFIERS2_PROPERTY).insertFirst(marker, null);
  }

  @SuppressWarnings("unchecked")
  private MethodDeclaration createNewConstructor(TypeDeclaration typeDecl2, AST ast) {
    MethodDeclaration newConstructor = ast.newMethodDeclaration();
    newConstructor.setConstructor(true);
    newConstructor.setExtraDimensions(0);
    newConstructor.setJavadoc(null);
    int modifier = Modifier.PUBLIC & Modifier.CONSTRUCTOR_INVOCATION;
    newConstructor.modifiers().addAll(ASTNodeFactory.newModifiers(ast, modifier));
    newConstructor.setName(ast.newSimpleName(typeDecl.getName().toString()));

    return newConstructor;

  }

}
TOP

Related Classes of org.springframework.ide.eclipse.quickfix.jdt.proposals.AddAutowiredConstructorCompletionProposal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.