001package ch.qos.logback.core.model.processor;
002
003import ch.qos.logback.core.Appender;
004import ch.qos.logback.core.Context;
005import ch.qos.logback.core.joran.JoranConstants;
006import ch.qos.logback.core.model.AppenderRefModel;
007import ch.qos.logback.core.model.Model;
008import ch.qos.logback.core.spi.AppenderAttachable;
009
010import java.util.Map;
011
012import static ch.qos.logback.core.model.processor.AppenderDeclarationAnalyser.isAppenderDeclared;
013
014public class AppenderRefModelHandler extends ModelHandlerBase {
015    boolean inError = false;
016
017    public AppenderRefModelHandler(Context context) {
018        super(context);
019    }
020
021    static public ModelHandlerBase makeInstance(Context context, ModelInterpretationContext ic) {
022        return new AppenderRefModelHandler(context);
023    }
024
025    @Override
026    protected Class<? extends AppenderRefModel> getSupportedModelClass() {
027        return AppenderRefModel.class;
028    }
029
030    @Override
031    public void handle(ModelInterpretationContext interpContext, Model model) throws ModelHandlerException {
032
033        Object o = interpContext.peekObject();
034
035        if (!(o instanceof AppenderAttachable)) {
036            inError = true;
037            String errMsg = "Could not find an AppenderAttachable at the top of execution stack. Near "
038                    + model.idString();
039            addError(errMsg);
040            return;
041        }
042
043        AppenderRefModel appenderRefModel = (AppenderRefModel) model;
044        AppenderAttachable<?> appenderAttachable = (AppenderAttachable<?>) o;
045
046        attachReferencedAppenders(interpContext, appenderRefModel, appenderAttachable);
047
048    }
049
050    @SuppressWarnings({ "unchecked", "rawtypes" })
051    void attachReferencedAppenders(ModelInterpretationContext mic, AppenderRefModel appenderRefModel,
052            AppenderAttachable<?> appenderAttachable) {
053        String appenderName = mic.subst(appenderRefModel.getRef());
054
055        if(!isAppenderDeclared(mic, appenderName)) {
056            addWarn("Appender named [" + appenderName + "] could not be found. Skipping attachment to "+appenderAttachable+".");
057            return;
058        }
059
060        Map<String, Appender> appenderBag = (Map<String, Appender>) mic.getObjectMap().get(JoranConstants.APPENDER_BAG);
061
062        Appender appender = appenderBag.get(appenderName);
063        if (appender == null) {
064            addError("Failed to find appender named [" + appenderName + "]");
065        } else {
066            addInfo("Attaching appender named [" + appenderName + "] to " + appenderAttachable);
067            appenderAttachable.addAppender(appender);
068        }
069
070    }
071}