001package ch.qos.logback.classic.joran.sanity;
002
003import ch.qos.logback.classic.model.LoggerModel;
004import ch.qos.logback.classic.model.RootLoggerModel;
005import ch.qos.logback.core.joran.sanity.Pair;
006import ch.qos.logback.core.joran.sanity.SanityChecker;
007import ch.qos.logback.core.model.AppenderModel;
008import ch.qos.logback.core.model.Model;
009import ch.qos.logback.core.model.conditional.IfModel;
010import ch.qos.logback.core.spi.ContextAwareBase;
011
012import java.util.ArrayList;
013import java.util.List;
014
015import static ch.qos.logback.core.CoreConstants.CODES_URL;
016
017public class IfNestedWithinSecondPhaseElementSC extends ContextAwareBase implements SanityChecker {
018
019    static final public String NESTED_IF_WARNING_URL = CODES_URL+ "#nested_if_element";
020
021    @Override
022    public void check(Model model) {
023        if (model == null)
024            return;
025
026        List<Model> secondPhaseModels = new ArrayList<>();
027        deepFindAllModelsOfType(AppenderModel.class, secondPhaseModels, model);
028        deepFindAllModelsOfType(LoggerModel.class, secondPhaseModels, model);
029        deepFindAllModelsOfType(RootLoggerModel.class, secondPhaseModels, model);
030
031        List<Pair<Model, Model>> nestedPairs = deepFindNestedSubModelsOfType(IfModel.class, secondPhaseModels);
032
033        if (nestedPairs.isEmpty())
034            return;
035
036        addWarn("<if> elements cannot be nested within an <appender>, <logger> or <root> element");
037        addWarn("See also " + NESTED_IF_WARNING_URL);
038        for (Pair<Model, Model> pair : nestedPairs) {
039            Model p = pair.first;
040            int pLine = p.getLineNumber();
041            Model s = pair.second;
042            int sLine = s.getLineNumber();
043            addWarn("Element <"+p.getTag()+"> at line " + pLine + " contains a nested <"+s.getTag()+"> element at line " +sLine);
044        }
045    }
046
047    @Override
048    public String toString() {
049        return "IfNestedWithinSecondPhaseElementSC";
050    }
051}