Package org.jbehave.plugin.idea

Source Code of org.jbehave.plugin.idea.JBehaveConfigurationType

package org.jbehave.plugin.idea;

import com.intellij.execution.LocatableConfigurationType;
import com.intellij.execution.Location;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NonNls;

import javax.swing.*;

public class JBehaveConfigurationType implements LocatableConfigurationType {
    private final ConfigurationFactory factory;

  public JBehaveConfigurationType() {
        this.factory = new ConfigurationFactory(this) {

            public RunConfiguration createTemplateConfiguration(Project project) {
                return new JBehaveRunConfiguration(project, this, "");
            }
        };
    }

    public String getDisplayName() {
        return "JBehave";
    }

    public String getConfigurationTypeDescription() {
        return "JBehave Configuration";
    }

    public Icon getIcon() {
        return Icons.LOGO;
    }

    public ConfigurationFactory[] getConfigurationFactories() {
        return new ConfigurationFactory[]{factory};
    }

    @NonNls
    public String getComponentName() {
        return "#org.jbehave.plugin.idea.JBehaveConfigurationType";
    }

    public void initComponent() {
    }

    public void disposeComponent() {
    }

    public boolean isConfigurationByElement(RunConfiguration configuration, Project project, PsiElement element) {
        PsiClass behaviorClass = getBehaviorClass(element);
        if (behaviorClass == null)
            return false;
        JBehaveRunConfiguration runConfiguration = ((JBehaveRunConfiguration) configuration);
        return Comparing.equal(ClassUtil.fullName(behaviorClass), runConfiguration.getBehaviorClass())
                && Comparing.equal(getBehaviourMethodName(element), runConfiguration.getBehaviourMethod());
    }

    private String getBehaviourMethodName(PsiElement element) {
        PsiMethod method = getBehaviourMethodElement(element);
        return method == null ? null : method.getName();
    }

    public PsiClass getBehaviorClass(PsiElement element) {
        for (PsiElement current = element; current != null; current = current.getParent()) {
            if (current instanceof PsiClass) {
                PsiClass currentClass = (PsiClass) current;
                if (isBehaviorClass(currentClass)) {
                    return currentClass;
                }
            } else if (current instanceof PsiFile) {
                PsiClass psiClass = getMainClass((PsiFile) current);
                if (psiClass != null && isBehaviorClass(psiClass)) {
                    return psiClass;
                }
            }
        }
        PsiFile file = element.getContainingFile();
        if (file instanceof PsiJavaFile) {
            PsiClass[] definedClasses = ((PsiJavaFile) file).getClasses();
            for (int i = 0; i < definedClasses.length; i++) {
                PsiClass definedClass = definedClasses[i];
                if (isBehaviorClass(definedClass)) {
                    return definedClass;
                }
            }
            for (int i = 0; i < definedClasses.length; i++) {
                PsiClass definedClass = definedClasses[i];
                PsiClass behaviorCandidate = checkIfThereIsOneWithBehaviorAtEnd(definedClass);
                if (behaviorCandidate != null && isBehaviorClass(behaviorCandidate)) {
                    return behaviorCandidate;
                }
            }
        }
        return null;
    }

    private PsiClass checkIfThereIsOneWithBehaviorAtEnd(PsiClass psiClass) {
        String nameToCheck = psiClass.getQualifiedName() + "Behavior";
        Project project = psiClass.getProject();
        return PsiManager.getInstance(project).findClass(nameToCheck, GlobalSearchScope.allScope(project));
    }

    private PsiClass getMainClass(PsiFile psiFile) {
        if (psiFile instanceof PsiJavaFile) {
            PsiJavaFile javaFile = (PsiJavaFile) psiFile;
            PsiClass[] definedClasses = javaFile.getClasses();
            for (int i = 0; i < definedClasses.length; i++) {
                PsiClass definedClass = definedClasses[i];
                if (isPublic(definedClass)) {
                    return definedClass;
                }
            }
        }
        return null;
    }

    private boolean isBehaviorClass(PsiClass psiClass) {
        if (!isRunnableClass(psiClass)) {
            return false;
        }
        return implementsBehaviorsInterface(psiClass) || containsShouldMethod(psiClass);
    }

    private boolean implementsBehaviorsInterface(PsiClass psiClass) {
        PsiClassType[] interfaces = psiClass.getImplementsListTypes();
        for (int i = 0; i < interfaces.length; i++) {
            PsiClassType anInterface = interfaces[i];
            if (Constants.BEHAVIOURS_INTERFACE.equals(anInterface.resolve().getQualifiedName())) {
                return true;
            }
        }
        return false;
    }

    private boolean containsShouldMethod(PsiClass psiClass) {
        PsiMethod[] methods = psiClass.getAllMethods();
        for (int i = 0; i < methods.length; i++) {
            if (isBehaviorMethod(methods[i])) {
                return true;
            }
        }
        return false;
    }

    private boolean isRunnableClass(PsiClass psiClass) {
        return isPublic(psiClass) && !psiClass.isInterface() && !isAbstract(psiClass);
    }

    private boolean isAbstract(PsiModifierListOwner definition) {
        return definition.getModifierList().hasModifierProperty("abstract");
    }

    private boolean isBehaviorMethod(PsiMethod method) {
        return method.getName().startsWith("should") && isPublic(method) && isVoid(method);
    }

    private boolean isPublic(PsiModifierListOwner definition) {
        PsiModifierList modifierList = definition.getModifierList();
        return modifierList != null && modifierList.hasModifierProperty("public");
    }

    private boolean isVoid(PsiMethod method) {
        return PsiType.VOID.equals(method.getReturnType());
    }

    public RunnerAndConfigurationSettings createConfigurationByLocation(Location location) {
        PsiClass behaviorClass = getBehaviorClass(location.getPsiElement());
        if (behaviorClass == null) {
            return null;
        }
        return new JBehaveConfigurationProducer(behaviorClass, this).createProducer(location, null).getConfiguration();
    }

    public static JBehaveConfigurationType getInstance() {
        return ApplicationManager.getApplication().getComponent(JBehaveConfigurationType.class);
    }

    public PsiMethod getBehaviourMethodElement(PsiElement psiElement) {
        if (psiElement instanceof PsiIdentifier && psiElement.getParent() instanceof PsiMethod) {
            PsiMethod method = (PsiMethod) psiElement.getParent();
            if (method.getName().startsWith("should")) {
                return method;
            }
        }
        return null;
    }
}
TOP

Related Classes of org.jbehave.plugin.idea.JBehaveConfigurationType

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.