001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2024, 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 v1.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.CoreConstants;
019import ch.qos.logback.core.model.ConversionRuleModel;
020import ch.qos.logback.core.model.Model;
021import ch.qos.logback.core.pattern.DynamicConverter;
022import ch.qos.logback.core.pattern.color.ConverterSupplierByClassName;
023import ch.qos.logback.core.util.OptionHelper;
024
025import java.util.HashMap;
026import java.util.Map;
027import java.util.function.Supplier;
028
029import static ch.qos.logback.core.joran.JoranConstants.CONVERSION_WORD_ATTRIBUTE;
030
031public class ConversionRuleModelHandler extends ModelHandlerBase {
032
033    private boolean inError;
034
035    public ConversionRuleModelHandler(Context context) {
036        super(context);
037    }
038
039    static public ConversionRuleModelHandler makeInstance(Context context, ModelInterpretationContext mic) {
040        return new ConversionRuleModelHandler(context);
041    }
042
043    @Override
044    public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
045
046        ConversionRuleModel conversionRuleModel = (ConversionRuleModel) model;
047        String converterClass = conversionRuleModel.getClassName();
048
049        if (OptionHelper.isNullOrEmptyOrAllSpaces(converterClass)) {
050            addWarn("Missing className. This should have been caught earlier.");
051            inError = true;
052            return;
053        } else {
054            converterClass = mic.getImport(converterClass);
055        }
056
057        String conversionWord = conversionRuleModel.getConversionWord();
058
059
060        try {
061            Map<String, Supplier<DynamicConverter>> ruleRegistry = (Map<String, Supplier<DynamicConverter>>) context
062                    .getObject(CoreConstants.PATTERN_RULE_REGISTRY);
063            if (ruleRegistry == null) {
064                ruleRegistry = new HashMap<>();
065                context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
066            }
067            // put the new rule into the rule registry
068            addInfo("registering conversion word " + conversionWord + " with class [" + converterClass + "]");
069            ConverterSupplierByClassName converterSupplierByClassName = new ConverterSupplierByClassName(conversionWord, converterClass);
070            converterSupplierByClassName.setContext(getContext());
071            ruleRegistry.put(conversionWord, converterSupplierByClassName);
072        } catch (Exception oops) {
073            inError = true;
074            String errorMsg = "Could not add conversion rule to PatternLayout.";
075            addError(errorMsg);
076        }
077
078
079
080    }
081}