001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2022, 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 */ 014package ch.qos.logback.core.model.processor; 015 016import ch.qos.logback.core.Context; 017import ch.qos.logback.core.joran.action.ActionUtil; 018import ch.qos.logback.core.joran.action.ActionUtil.Scope; 019import ch.qos.logback.core.model.DefineModel; 020import ch.qos.logback.core.model.Model; 021import ch.qos.logback.core.spi.LifeCycle; 022import ch.qos.logback.core.spi.PropertyDefiner; 023import ch.qos.logback.core.util.OptionHelper; 024 025/** 026 * Instantiate class for define property value. Get future property name and 027 * property definer class from attributes. Some property definer properties 028 * could be used. After defining put new property to context. 029 * 030 * @author Aleksey Didik 031 */ 032public class DefineModelHandler extends ModelHandlerBase { 033 034 boolean inError; 035 PropertyDefiner definer; 036 String propertyName; 037 Scope scope; 038 039 public DefineModelHandler(Context context) { 040 super(context); 041 } 042 043 static public DefineModelHandler makeInstance(Context context, ModelInterpretationContext ic) { 044 return new DefineModelHandler(context); 045 } 046 047 @Override 048 protected Class<DefineModel> getSupportedModelClass() { 049 return DefineModel.class; 050 } 051 052 @Override 053 public void handle(ModelInterpretationContext interpretationContext, Model model) throws ModelHandlerException { 054 definer = null; 055 inError = false; 056 propertyName = null; 057 058 DefineModel defineModel = (DefineModel) model; 059 060 propertyName = defineModel.getName(); 061 String scopeStr = defineModel.getScopeStr(); 062 063 scope = ActionUtil.stringToScope(scopeStr); 064 065 if (OptionHelper.isNullOrEmpty(propertyName)) { 066 addError("Missing property name for property definer. Near [" + model.getTag() + "] line " 067 + model.getLineNumber()); 068 inError = true; 069 } 070 071 // read property definer class name 072 String className = defineModel.getClassName(); 073 if (OptionHelper.isNullOrEmpty(className)) { 074 addError("Missing class name for property definer. Near [" + model.getTag() + "] line " 075 + model.getLineNumber()); 076 inError = true; 077 } else { 078 className = interpretationContext.getImport(className); 079 } 080 081 if (inError) 082 return; 083 084 // try to instantiate property definer 085 try { 086 addInfo("About to instantiate property definer of type [" + className + "]"); 087 definer = (PropertyDefiner) OptionHelper.instantiateByClassName(className, PropertyDefiner.class, context); 088 definer.setContext(context); 089 interpretationContext.pushObject(definer); 090 } catch (Exception oops) { 091 inError = true; 092 addError("Could not create an PropertyDefiner of type [" + className + "].", oops); 093 throw new ModelHandlerException(oops); 094 } 095 096 } 097 098 /** 099 * Now property definer is initialized by all properties and we can put property 100 * value to context 101 */ 102 @Override 103 public void postHandle(ModelInterpretationContext interpretationContext, Model model) throws ModelHandlerException { 104 if (inError) { 105 return; 106 } 107 108 Object o = interpretationContext.peekObject(); 109 110 if (o != definer) { 111 addWarn("The object at the of the stack is not the property definer for property named [" + propertyName 112 + "] pushed earlier."); 113 } else { 114 interpretationContext.popObject(); 115 if (definer instanceof LifeCycle) 116 ((LifeCycle) definer).start(); 117 118 // let's put defined property and value to context but only if it is 119 // not null 120 String propertyValue = definer.getPropertyValue(); 121 if (propertyValue != null) { 122 addInfo("Setting property " + propertyName + "=" + propertyValue + " in scope " + scope); 123 ActionUtil.setProperty(interpretationContext, propertyName, propertyValue, scope); 124 } 125 } 126 127 } 128}