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 */ 014package ch.qos.logback.core.model.processor; 015 016import java.util.Map; 017 018import ch.qos.logback.core.Appender; 019import ch.qos.logback.core.Context; 020import ch.qos.logback.core.joran.JoranConstants; 021import ch.qos.logback.core.model.AppenderModel; 022import ch.qos.logback.core.model.Model; 023import ch.qos.logback.core.spi.AppenderAttachable; 024import ch.qos.logback.core.spi.LifeCycle; 025import ch.qos.logback.core.util.OptionHelper; 026 027public class AppenderModelHandler<E> extends ModelHandlerBase { 028 Appender<E> appender; 029 private boolean inError = false; 030 private boolean skipped = false; 031 AppenderAttachable<E> appenderAttachable; 032 033 public AppenderModelHandler(Context context) { 034 super(context); 035 } 036 037 @SuppressWarnings("rawtypes") 038 static public ModelHandlerBase makeInstance(Context context, ModelInterpretationContext mic) { 039 return new AppenderModelHandler(context); 040 } 041 042 @Override 043 @SuppressWarnings("unchecked") 044 public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException { 045 this.appender = null; 046 this.inError = false; 047 048 AppenderModel appenderModel = (AppenderModel) model; 049 050 // appender names should not be subjected to substitution 051 String appenderName = mic.subst(appenderModel.getName()); 052 053 if (!mic.hasDependers(appenderName)) { 054 addWarn("Appender named [" + appenderName + "] not referenced. Skipping further processing."); 055 skipped = true; 056 appenderModel.markAsSkipped(); 057 return; 058 } 059 060 addInfo("Processing appender named [" + appenderName + "]"); 061 062 String originalClassName = appenderModel.getClassName(); 063 String className = mic.getImport(originalClassName); 064 065 try { 066 addInfo("About to instantiate appender of type [" + className + "]"); 067 068 appender = (Appender<E>) OptionHelper.instantiateByClassName(className, ch.qos.logback.core.Appender.class, 069 context); 070 appender.setContext(context); 071 appender.setName(appenderName); 072 mic.pushObject(appender); 073 } catch (Exception oops) { 074 inError = true; 075 addError("Could not create an Appender of type [" + className + "].", oops); 076 throw new ModelHandlerException(oops); 077 } 078 } 079 080 public void postHandle(ModelInterpretationContext mic, Model model) throws ModelHandlerException { 081 if (inError || skipped) { 082 return; 083 } 084 if (appender instanceof LifeCycle) { 085 ((LifeCycle) appender).start(); 086 } 087 mic.markStartOfNamedDependee(appender.getName()); 088 089 Object o = mic.peekObject(); 090 091 @SuppressWarnings("unchecked") 092 Map<String, Appender<E>> appenderBag = (Map<String, Appender<E>>) mic.getObjectMap() 093 .get(JoranConstants.APPENDER_BAG); 094 appenderBag.put(appender.getName(), appender); 095 096 if (o != appender) { 097 addWarn("The object at the of the stack is not the appender named [" + appender.getName() 098 + "] pushed earlier."); 099 } else { 100 mic.popObject(); 101 } 102 103 } 104 105}