com.sebrichard.mfgen.inspection.InspectingMetaFields.java Source code

Java tutorial

Introduction

Here is the source code for com.sebrichard.mfgen.inspection.InspectingMetaFields.java

Source

/*
 * (C) Copyright 2013 Sbastien Richard
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sebrichard.mfgen.inspection;

import com.google.common.collect.Sets;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtil;
import com.sebrichard.mfgen.MetaFieldUtil;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

public class InspectingMetaFields extends BaseJavaLocalInspectionTool {
    @NotNull
    public String getDisplayName() {
        return "Meta-field validations";
    }

    @NotNull
    public String getGroupDisplayName() {
        return GroupNames.BUGS_GROUP_NAME;
    }

    @NotNull
    public String getShortName() {
        return "ValidatingMetaField";
    }

    @NotNull
    @Override
    public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
        return new JavaElementVisitor() {

            @Override
            public void visitClass(PsiClass psiClass) {
                Set<String> acceptedMetaFieldNames = generateAcceptedMetaFieldNames(psiClass);

                Set<PsiField> metaFields = findMetaFields(psiClass);

                for (PsiField metaField : metaFields) {

                    if (!metaField.hasModifierProperty(PsiModifier.FINAL)) {
                        holder.registerProblem(metaField, "Meta-field not final");
                        continue;
                    }

                    if (!metaField.getType().equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
                        // The field with the 'meta-field' name pattern does not have the String type!
                        holder.registerProblem(metaField, "Meta-field is not a String");
                        continue;
                    }

                    PsiExpression initializer = metaField.getInitializer();
                    if (initializer != null) {
                        if (initializer instanceof PsiLiteral) {
                            PsiLiteral literal = (PsiLiteral) initializer;
                            if (literal.getValue() != null && literal.getValue() instanceof String) {
                                String initializationValue = (String) literal.getValue();
                                if (!StringUtils.equals(metaField.getName(),
                                        MetaFieldUtil.generateMetaFieldName(initializationValue))) {
                                    holder.registerProblem(metaField, "Meta-field name does not match its value");
                                    continue;
                                }
                            } else {
                                holder.registerProblem(metaField,
                                        "Meta-field initializing value is not a String value");
                                continue;
                            }
                        } else {
                            holder.registerProblem(metaField,
                                    "Meta-field initializing value is not a String constant value");
                            continue;
                        }
                    } else {
                        holder.registerProblem(metaField, "Uninitialized Meta-field");
                    }

                    if (!acceptedMetaFieldNames.contains(metaField.getName())) {
                        // We didn't find any matching field!
                        holder.registerProblem(metaField, "Did not find any matching non-static field.");
                        continue;
                    }
                }
            }

        };
    }

    private Set<String> generateAcceptedMetaFieldNames(PsiClass psiClass) {
        Set<String> acceptedMetaFields = Sets.newHashSet();

        for (PsiField field : psiClass.getAllFields()) {
            if (!field.hasModifierProperty(PsiModifier.STATIC)) {
                acceptedMetaFields.add(MetaFieldUtil.generateMetaFieldName(field.getName()));
            }
        }
        for (PsiMethod method : psiClass.getAllMethods()) {
            if (!method.hasModifierProperty(PsiModifier.STATIC) && PropertyUtil.isSimplePropertyGetter(method)) {
                String propertyName = PropertyUtil.getPropertyNameByGetter(method);
                acceptedMetaFields.add(MetaFieldUtil.generateMetaFieldName(propertyName));
            }
        }

        return acceptedMetaFields;
    }

    private Set<PsiField> findMetaFields(PsiClass psiClass) {
        Set<PsiField> metaFields = Sets.newHashSet();
        for (PsiField metaField : psiClass.getFields()) {
            if (MetaFieldUtil.isMetaField(metaField)) {
                metaFields.add(metaField);
            }
        }
        return metaFields;
    }

    public boolean isEnabledByDefault() {
        return true;
    }

    @NotNull
    @Override
    public HighlightDisplayLevel getDefaultLevel() {
        return HighlightDisplayLevel.ERROR;
    }

}