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.classic.tyler; 016 017import ch.qos.logback.classic.Level; 018import ch.qos.logback.classic.Logger; 019import ch.qos.logback.classic.LoggerContext; 020import ch.qos.logback.classic.joran.JoranConfigurator; 021import ch.qos.logback.classic.model.ConfigurationModel; 022import ch.qos.logback.classic.util.LevelUtil; 023import ch.qos.logback.core.Context; 024import ch.qos.logback.core.joran.GenericXMLConfigurator; 025import ch.qos.logback.core.model.Model; 026import ch.qos.logback.core.model.processor.ModelHandlerBase; 027import ch.qos.logback.core.model.util.PropertyModelHandlerHelper; 028import ch.qos.logback.core.model.util.VariableSubstitutionsHelper; 029import ch.qos.logback.core.spi.ContextAwareBase; 030import ch.qos.logback.core.spi.ContextAwarePropertyContainer; 031import ch.qos.logback.core.status.OnConsoleStatusListener; 032import ch.qos.logback.core.util.OptionHelper; 033import ch.qos.logback.core.util.StatusListenerConfigHelper; 034import ch.qos.logback.core.util.StringUtil; 035 036import java.util.Map; 037import java.util.function.Supplier; 038 039public class TylerConfiguratorBase extends ContextAwareBase implements ContextAwarePropertyContainer { 040 041 public static final String SET_CONTEXT_METHOD_NAME = "setContext"; 042 public static final String SET_CONTEXT_NAME_METHOD_NAME = "setContextName"; 043 public static final String SETUP_LOGGER_METHOD_NAME = "setupLogger"; 044 public static final String VARIABLE_SUBSTITUTIONS_HELPER_FIELD_NAME = "variableSubstitutionsHelper"; 045 public static final String PROPERTY_MODEL_HANDLER_HELPER_FIELD_NAME = "propertyModelHandlerHelper"; 046 047 // initialized via #setContext 048 protected VariableSubstitutionsHelper variableSubstitutionsHelper; 049 // context set in #setContext 050 protected PropertyModelHandlerHelper propertyModelHandlerHelper = new PropertyModelHandlerHelper(this); 051 052 protected Logger setupLogger(String loggerName, String levelString, Boolean additivity) { 053 LoggerContext loggerContext = (LoggerContext) context; 054 Logger logger = loggerContext.getLogger(loggerName); 055 if (!OptionHelper.isNullOrEmptyOrAllSpaces(levelString)) { 056 Level level = LevelUtil.levelStringToLevel(levelString); 057 logger.setLevel(level); 058 } 059 if (additivity != null) { 060 logger.setAdditive(additivity); 061 } 062 return logger; 063 } 064 065 @Override 066 public void setContext(Context context) { 067 super.setContext(context); 068 variableSubstitutionsHelper = new VariableSubstitutionsHelper(context); 069 propertyModelHandlerHelper.setContext(context); 070 } 071 072 protected void setContextName(String name) { 073 if (StringUtil.isNullOrEmpty(name)) { 074 addError("Cannot set context name to null or empty string"); 075 return; 076 } 077 try { 078 String substName = subst(name); 079 addInfo("Setting context name to [" + substName + "]"); 080 context.setName(substName); 081 } catch (IllegalStateException e) { 082 addError("Failed to rename context as [" + name + "]"); 083 } 084 } 085 086 protected void addOnConsoleStatusListener() { 087 StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener()); 088 } 089 090 /** 091 * Performs variable substitution. 092 * 093 * @param ref 094 * @return 095 */ 096 @Override 097 public String subst(String ref) { 098 return variableSubstitutionsHelper.subst(ref); 099 } 100 101 @Override 102 public void addSubstitutionProperty(String key, String value) { 103 variableSubstitutionsHelper.addSubstitutionProperty(key, value); 104 } 105 106 /** 107 * If a key is found in propertiesMap then return it. 108 */ 109 @Override 110 public String getProperty(String key) { 111 return variableSubstitutionsHelper.getProperty(key); 112 } 113 114 @Override 115 public Map<String, String> getCopyOfPropertyMap() { 116 return variableSubstitutionsHelper.getCopyOfPropertyMap(); 117 } 118 119 public boolean isNull(String k) { 120 String val = OptionHelper.propertyLookup(k, this, context); 121 return (val == null); 122 } 123 124 /** 125 * Method used in conditional evaluation 126 * 127 * @param k a property name 128 * @return true if the property is defined 129 * @since 1.5.4 130 */ 131 public boolean isDefined(String k) { 132 String val = OptionHelper.propertyLookup(k, this, context); 133 return (val != null); 134 } 135 136 /** 137 * Shorthand for {@link #property(String)}. 138 * 139 * @param k a property name 140 * @return value of property k 141 * @since 1.5.4 142 */ 143 public String p(String k) { 144 return property(k); 145 } 146 147 /** 148 * Return the value of the property named k. If the value is null, then the 149 * empty string is returned to avoid null checks. 150 * 151 * @param k property name 152 * @return the value of the property named k 153 * @since 1.5.4 154 */ 155 public String property(String k) { 156 String val = OptionHelper.propertyLookup(k, this, context); 157 if (val != null) 158 return val; 159 else 160 return ""; 161 } 162 163 private JoranConfigurator makeAnotherInstance() { 164 JoranConfigurator jc = new JoranConfigurator(); 165 jc.setContext(context); 166 return jc; 167 } 168 169 /** 170 * Return a supplier which supplies an instance of {@link JoranConfigurator} set to 171 * the same context the context of 'this'. 172 * @since 1.5.11 173 */ 174 @Override 175 public Supplier<? extends GenericXMLConfigurator> getConfiguratorSupplier() { 176 Supplier<? extends GenericXMLConfigurator> supplier = () -> this.makeAnotherInstance(); 177 return supplier; 178 } 179 180 // used by TylerIncludeModelHandler in logback-tyler 181 protected void processModelFromIncludedFile(Model modelFromIncludedFile) { 182 Supplier<? extends GenericXMLConfigurator > configuratorSupplier = this.getConfiguratorSupplier(); 183 GenericXMLConfigurator genericXMLConfigurator = configuratorSupplier.get(); 184 ConfigurationModel configurationModel = new ConfigurationModel(); 185 configurationModel.addSubModel(modelFromIncludedFile); 186 genericXMLConfigurator.processModel(configurationModel); 187 } 188}