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}