Package org.springframework.ide.eclipse.internal.bestpractices.quickfix

Source Code of org.springframework.ide.eclipse.internal.bestpractices.quickfix.AbstractCreateMethodMarkerResolution

/*******************************************************************************
*  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.internal.bestpractices.quickfix;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
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.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IMarkerResolution2;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.springframework.ide.eclipse.bestpractices.BestPracticesPluginConstants;
import org.springsource.ide.eclipse.commons.core.StatusHandler;


/**
* Resolution for missing property markers. Creates a corresponding setter in
* the class referenced by the bean definition.
* @author Wesley Coelho
* @author Steffen Pingel
* @author Leo Dos Santos
* @author Christian Dupuis
*/
public abstract class AbstractCreateMethodMarkerResolution implements IMarkerResolution2 {

  private static final String MESSAGE_ATTRIBUTE_KEY = "message";

  private String markerMessage = "";

  public AbstractCreateMethodMarkerResolution(IMarker marker) {
    markerMessage = marker.getAttribute(MESSAGE_ATTRIBUTE_KEY, "");
  }

  protected String extractQuotedString(String startTag, String message) {
    int startPos = message.indexOf(startTag) + startTag.length();
    int endPos = message.indexOf("'", startPos);
    return message.substring(startPos, endPos);
  }

  @SuppressWarnings("unchecked")
  protected List<Expression> getArguments(Expression invocationExpression) {
    MethodInvocation methodInvocation = (MethodInvocation) invocationExpression;
    List<Expression> arguments = new ArrayList<Expression>();
    for (Iterator<Expression> argumentIter = methodInvocation.arguments().iterator(); argumentIter.hasNext();) {
      Expression argumentExpression = argumentIter.next();
      arguments.add(argumentExpression);
    }
    return arguments;
  }

  public abstract String getDescription();

  public Image getImage() {
    return null;
  }

  public abstract String getLabel();

  protected String getMarkerMessage() {
    return markerMessage;
  }

  protected Expression getMockMethodInvocation() {
    ASTParser fooParser = ASTParser.newParser(AST.JLS3);
    fooParser.setKind(ASTParser.K_STATEMENTS);
    String mockMethodInvocationCode = getNewMethodName() + "(" + getNewMethodParameters() + ");";
    fooParser.setSource(mockMethodInvocationCode.toCharArray());
    fooParser.setResolveBindings(true);
    ASTNode parsedAstNode = fooParser.createAST(null);
    Block codeBlock = (Block) parsedAstNode;
    ExpressionStatement methodInvocationExpressionStatement = (ExpressionStatement) codeBlock.statements().get(0);
    return methodInvocationExpressionStatement.getExpression();
  }

  protected abstract String getNewMethodName();

  /**
   * Override to provide parameters for the new method name. Parameters should
   * not include types and should be as they would appear in a method call to
   * the new method, e.g. "object" or "obj1, obj2".
   */
  protected String getNewMethodParameters() {
    return "";
  }

  protected abstract String getTargetClass();

  protected ITypeBinding getTargetTypeBinding(IJavaProject javaProject, IType targetType) {
    ASTParser bindingParser = ASTParser.newParser(AST.JLS3);
    bindingParser.setKind(ASTParser.K_COMPILATION_UNIT);
    bindingParser.setSource(targetType.getCompilationUnit());
    bindingParser.setResolveBindings(true);
    bindingParser.setProject(javaProject);
    IBinding[] bindings = bindingParser
        .createBindings(new IJavaElement[] { targetType }, new NullProgressMonitor());
    ITypeBinding typeBinding = (ITypeBinding) bindings[0];
    return typeBinding;
  }

  public void run(IMarker marker) {

    IProject project = marker.getResource().getProject();
    IJavaProject javaProject = JavaCore.create(project);
    IType targetType = null;
    try {
      targetType = javaProject.findType(getTargetClass());
    }
    catch (JavaModelException e) {
      StatusHandler.log(e.getStatus());
      MessageDialog.openError(Display.getDefault().getActiveShell(), "Quick Fix Error", "Could not find class '"
          + getTargetClass() + "'");
      return;
    }
    if (targetType == null) {
      StatusHandler.log(new Status(Status.ERROR, BestPracticesPluginConstants.PLUGIN_ID, "Could not find class '"
          + getTargetClass() + "'"));
      MessageDialog.openError(Display.getDefault().getActiveShell(), "Quick Fix Error", "Could not find class '"
          + getTargetClass() + "'");
      return;
    }

    Expression mockMethodInvocation = getMockMethodInvocation();

    ITypeBinding typeBinding = getTargetTypeBinding(javaProject, targetType);

    List<Expression> arguments = getArguments(mockMethodInvocation);

    Image image = JavaPluginImages.get(JavaPluginImages.IMG_MISC_PUBLIC);

    // XXX e3.4 work around changed class name in Eclipse 3.4
    ICompletionProposal newMethodCompletionProposal;
    try {
      Class<?> clazz;
      try {
        // Eclipse 3.3
        clazz = Class.forName("org.eclipse.jdt.internal.ui.text.correction.NewMethodCompletionProposal");
      }
      catch (ClassNotFoundException e) {
        // Eclipse 3.4
        clazz = Class
            .forName("org.eclipse.jdt.internal.ui.text.correction.proposals.NewMethodCorrectionProposal");
      }
      Constructor<?> constructor = clazz.getConstructor(String.class, ICompilationUnit.class, ASTNode.class,
          List.class, ITypeBinding.class, int.class, Image.class);
      newMethodCompletionProposal = (ICompletionProposal) constructor.newInstance("Add missing property",
          targetType.getCompilationUnit(), mockMethodInvocation, arguments, typeBinding, 0, image);
    }
    catch (Throwable t) {
      StatusHandler.log(new Status(IStatus.ERROR, BestPracticesPluginConstants.PLUGIN_ID,
          "Problems occured when creating completion proposal", t));
      MessageDialog.openError(Display.getDefault().getActiveShell(), "Quick Fix Error",
          "Could not execute correction proposal");
      return;
    }

    // Get the XML document model
    IStructuredModel model = null;
    try {
      model = XmlQuickFixUtil.getModel(marker);
      // Execute Quick Fix
      newMethodCompletionProposal.apply(model.getStructuredDocument());
    }
    catch (CoreException e) {
      StatusHandler.log(e.getStatus());
      MessageDialog.openError(Display.getDefault().getActiveShell(), "Quick Fix Error",
          "Could not find error marker");
    }
    finally {
      if (model != null) {
        model.releaseFromEdit();
        model = null;
      }
    }

  }
}
TOP

Related Classes of org.springframework.ide.eclipse.internal.bestpractices.quickfix.AbstractCreateMethodMarkerResolution

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.