Package com.googlecode.generatefluentinterface

Source Code of com.googlecode.generatefluentinterface.GenerateFluentInterfaceActionHandlerImpl

package com.googlecode.generatefluentinterface;

import com.intellij.codeInsight.generation.PsiFieldMember;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.util.MemberChooser;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
* <p>
* <p> Date: 6/1/11 Time: 5:12 PM </p>
*
* @author Felix.ZHU
* @since v
*/
class GenerateFluentInterfaceActionHandlerImpl extends EditorWriteActionHandler {
// ------------------------------ FIELDS ------------------------------


// --------------------------- CONSTRUCTORS ---------------------------

    public GenerateFluentInterfaceActionHandlerImpl() {
    }

// -------------------------- OTHER METHODS --------------------------

    @Override
    public void executeWriteAction(final Editor editor, final DataContext dataContext) {
        final Project project = LangDataKeys.PROJECT.getData(dataContext);

        assert project != null;

        PsiClass clazz = getSubjectClass(editor, dataContext);

        if (clazz == null) {
            return;
        }

        if (clazz.isInterface()) {
            HintManager.getInstance().showErrorHint(editor, "Can't generate fluent interface methods in an interface.");
        }

        doExecuteAction(project, clazz, editor);
    }

    @Nullable
    private PsiClass getSubjectClass(Editor editor, DataContext dataContext) {
        PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
        if (file == null) {
            return null;
        }

        int offset = editor.getCaretModel().getOffset();
        PsiElement context = file.findElementAt(offset);

        if (context == null) {
            return null;
        }

        PsiClass clazz = PsiTreeUtil.getParentOfType(context, PsiClass.class, false);
        if (clazz == null) {
            return null;
        }

        return clazz;

    }

    private void doExecuteAction(final Project project, final PsiClass psiClass, final Editor editor) {
        final Collection<PsiField> candidateFields = pickupCandidateFields(psiClass);

        if (candidateFields.size() == 0) {
            HintManager.getInstance().showErrorHint(editor, "No members to generate fluent interface have been found.");
            return;
        }

        List<PsiFieldMember> psiFieldMembers = new LinkedList<PsiFieldMember>();
        for (PsiField candidateField : candidateFields) {
            psiFieldMembers.add(new PsiFieldMember(candidateField));
        }

        chooseMemberAndRun(project,
                editor, psiClass,
                psiFieldMembers.toArray(new PsiFieldMember[psiFieldMembers.size()])
        );
    }

    private Collection<PsiField> pickupCandidateFields(final PsiClass psiClass) {
        final List<PsiField> fields = getCandidateFields(psiClass);
        return filterExistCandidates(psiClass, fields);
    }

    private List<PsiField> getCandidateFields(final PsiClass psiClass) {
        PsiField[] allFields = psiClass.getAllFields();
        List<PsiField> candidateFields = new LinkedList<PsiField>();
        for (PsiField field : allFields) {
            PsiModifierList psiModifierList = field.getModifierList();
            if (psiModifierList != null && isCandidateField(psiModifierList)) {
                candidateFields.add(field);
            }
        }

        return candidateFields;
    }

    private boolean isCandidateField(final PsiModifierList psiModifierList) {
        return (!(psiModifierList.hasModifierProperty(PsiModifier.FINAL)) &&
                !(psiModifierList.hasModifierProperty(PsiModifier.STATIC)));
    }

    private Collection<PsiField> filterExistCandidates(final PsiClass psiClass, final List<PsiField> candidateFields) {
        Collection<PsiField> result = new LinkedList<PsiField>();

        FiMethodTester tester = new FiMethodTester(psiClass);

        for (PsiField candidateField : candidateFields) {
            if (!tester.hasReadWriteMethod(candidateField)) {
                result.add(candidateField);
            }
        }
        return result;
    }

    private void chooseMemberAndRun(final Project project,
                                    final Editor editor, final PsiClass clazz,
                                    final PsiFieldMember[] classMembers) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (project.isDisposed()) {
                    return;
                }

                GenerateFluentInterfaceMemberChooser chooser
                        = new GenerateFluentInterfaceMemberChooser(classMembers, project);
                chooser.setTitle("Generate Fluent Interface Members");
                chooser.selectElements(classMembers);

                chooser.show();


                if (chooser.getExitCode() == MemberChooser.OK_EXIT_CODE) {
                    final List<PsiFieldMember> list = chooser.getSelectedElements();
                    final String setterPrefix = chooser.getSetterPrefix();
                    final boolean generateGetter = chooser.generateGetters();
                    if (list == null) {
                        return;
                    }

                    GenerateFluentInterfaceApplicationComponent applicationComponent
                            = ApplicationManager.getApplication()
                            .getComponent(GenerateFluentInterfaceApplicationComponent.class);

                    applicationComponent.updateIsGeneratingGetters(generateGetter);
                    applicationComponent.updateSetterPrefix(setterPrefix);

                    final List<PsiField> chosenFields = new LinkedList<PsiField>();
                    for (PsiFieldMember classMember : list) {
                        chosenFields.add(classMember.getElement());
                    }

                    executeGenerateLater(project,
                            editor, clazz,
                            chosenFields.toArray(new PsiField[chosenFields.size()]),
                            setterPrefix,
                            generateGetter
                    );
                }
            }
        });
    }

    private void executeGenerateLater(final Project project,
                                      final Editor editor, final PsiClass clazz,
                                      final PsiField[] chosenFields,
                                      final String setterPrefix,
                                      final boolean generateGetter) {
        CommandProcessor.getInstance().executeCommand(project, new Runnable() {
            public void run() {
                ApplicationManager.getApplication().runWriteAction(new Runnable() {
                    public void run() {
                        new GenerateFluentInterfaceWorker(project, editor, clazz,
                                setterPrefix, generateGetter)
                                .execute(chosenFields);
                    }
                });
            }
        }, "GenerateFluentInterface", null);
    }
}
TOP

Related Classes of com.googlecode.generatefluentinterface.GenerateFluentInterfaceActionHandlerImpl

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.