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 static ch.qos.logback.core.joran.action.Action.CLASS_ATTRIBUTE;
018
019import java.util.Map;
020
021import ch.qos.logback.core.Context;
022import ch.qos.logback.core.CoreConstants;
023import ch.qos.logback.core.boolex.EventEvaluator;
024import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
025import ch.qos.logback.core.model.EventEvaluatorModel;
026import ch.qos.logback.core.model.Model;
027import ch.qos.logback.core.spi.LifeCycle;
028import ch.qos.logback.core.util.OptionHelper;
029
030public class EventEvaluatorModelHandler extends ModelHandlerBase {
031
032    EventEvaluator<?> evaluator;
033    boolean inError = false;
034
035    public EventEvaluatorModelHandler(Context context) {
036        super(context);
037    }
038
039    static public ModelHandlerBase makeInstance(Context context, ModelInterpretationContext ic) {
040        return new EventEvaluatorModelHandler(context);
041    }
042
043    @Override
044    protected Class<EventEvaluatorModel> getSupportedModelClass() {
045        return EventEvaluatorModel.class;
046    }
047
048    @Override
049    public void handle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
050        EventEvaluatorModel eem = (EventEvaluatorModel) model;
051
052        String className = eem.getClassName();
053        if (OptionHelper.isNullOrEmptyOrAllSpaces(className)) {
054            String defaultClassName = defaultClassName(intercon, eem);
055            if (OptionHelper.isNullOrEmptyOrAllSpaces(defaultClassName)) {
056                inError = true;
057                addError("Mandatory \"" + CLASS_ATTRIBUTE + "\" attribute missing for <evaluator>");
058                addError("No default classname could be found.");
059                return;
060            } else {
061                addInfo("Assuming default evaluator class [" + defaultClassName + "]");
062                className = defaultClassName;
063            }
064        } else {
065            className = intercon.getImport(className);
066        }
067
068        String evaluatorName = intercon.subst(eem.getName());
069        try {
070            evaluator = (EventEvaluator<?>) OptionHelper.instantiateByClassName(className,
071                    ch.qos.logback.core.boolex.EventEvaluator.class, context);
072            evaluator.setContext(this.context);
073            evaluator.setName(evaluatorName);
074            intercon.pushObject(evaluator);
075
076        } catch (Exception oops) {
077            inError = true;
078            addError("Could not create evaluator of type " + className + "].", oops);
079        }
080
081    }
082
083    private String defaultClassName(ModelInterpretationContext mic, EventEvaluatorModel model) {
084        DefaultNestedComponentRegistry registry = mic.getDefaultNestedComponentRegistry();
085        return registry.findDefaultComponentTypeByTag(model.getTag());
086    }
087
088    @Override
089    public void postHandle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
090        if (inError) {
091            return;
092        }
093
094        if (evaluator instanceof LifeCycle) {
095            ((LifeCycle) evaluator).start();
096            addInfo("Starting evaluator named [" + evaluator.getName() + "]");
097        }
098
099        Object o = intercon.peekObject();
100
101        if (o != evaluator) {
102            addWarn("The object on the top the of the stack is not the evaluator pushed earlier.");
103        } else {
104            intercon.popObject();
105
106            try {
107                @SuppressWarnings("unchecked")
108                Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context
109                        .getObject(CoreConstants.EVALUATOR_MAP);
110                if (evaluatorMap == null) {
111                    addError("Could not find EvaluatorMap");
112                } else {
113                    evaluatorMap.put(evaluator.getName(), evaluator);
114                }
115            } catch (Exception ex) {
116                addError("Could not set evaluator named [" + evaluator + "].", ex);
117            }
118        }
119    }
120
121}