001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v2.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014
015package ch.qos.logback.core.model.processor;
016
017import ch.qos.logback.core.Context;
018import ch.qos.logback.core.model.Model;
019import ch.qos.logback.core.model.StatusListenerModel;
020import ch.qos.logback.core.spi.ContextAware;
021import ch.qos.logback.core.spi.LifeCycle;
022import ch.qos.logback.core.status.StatusListener;
023import ch.qos.logback.core.util.OptionHelper;
024
025public class StatusListenerModelHandler extends ModelHandlerBase {
026
027    boolean inError = false;
028    Boolean effectivelyAdded = null;
029    StatusListener statusListener = null;
030
031    public StatusListenerModelHandler(Context context) {
032        super(context);
033    }
034
035    static public ModelHandlerBase makeInstance(Context context, ModelInterpretationContext ic) {
036        return new StatusListenerModelHandler(context);
037    }
038
039    @Override
040    protected Class<StatusListenerModel> getSupportedModelClass() {
041        return StatusListenerModel.class;
042    }
043
044    @Override
045    public void handle(ModelInterpretationContext ic, Model model) throws ModelHandlerException {
046
047        StatusListenerModel slModel = (StatusListenerModel) model;
048
049        String className = slModel.getClassName();
050
051        if (OptionHelper.isNullOrEmptyOrAllSpaces(className)) {
052            addError("Empty class name for StatusListener");
053            inError = true;
054            return;
055        } else {
056            className = ic.getImport(className);
057        }
058
059        try {
060            statusListener = (StatusListener) OptionHelper.instantiateByClassName(className, StatusListener.class,
061                    context);
062            effectivelyAdded = ic.getContext().getStatusManager().add(statusListener);
063            if (statusListener instanceof ContextAware) {
064                ((ContextAware) statusListener).setContext(context);
065            }
066            addInfo("Added status listener of type [" + slModel.getClassName() + "]");
067            ic.pushObject(statusListener);
068        } catch (Exception e) {
069            inError = true;
070            addError("Could not create an StatusListener of type [" + slModel.getClassName() + "].", e);
071            throw new ModelHandlerException(e);
072        }
073    }
074
075    @Override
076    public void postHandle(ModelInterpretationContext mic, Model m) {
077        if (inError) {
078            return;
079        }
080
081        if (isEffectivelyAdded() && statusListener instanceof LifeCycle) {
082            ((LifeCycle) statusListener).start();
083        }
084        Object o = mic.peekObject();
085        if (o != statusListener) {
086            addWarn("The object at the of the stack is not the statusListener pushed earlier.");
087        } else {
088            mic.popObject();
089        }
090    }
091
092    private boolean isEffectivelyAdded() {
093        if (effectivelyAdded == null)
094            return false;
095        return effectivelyAdded;
096    }
097}