001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2021, 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 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 String appenderName = mic.subst(appenderModel.getName()); 051 052 if (!mic.hasDependers(appenderName)) { 053 addWarn("Appender named [" + appenderName + "] not referenced. Skipping further processing."); 054 skipped = true; 055 appenderModel.markAsSkipped(); 056 return; 057 } 058 059 addInfo("Processing appender named [" + appenderName + "]"); 060 061 String originalClassName = appenderModel.getClassName(); 062 String className = mic.getImport(originalClassName); 063 064 try { 065 addInfo("About to instantiate appender of type [" + className + "]"); 066 067 appender = (Appender<E>) OptionHelper.instantiateByClassName(className, ch.qos.logback.core.Appender.class, 068 context); 069 appender.setContext(context); 070 appender.setName(appenderName); 071 mic.pushObject(appender); 072 } catch (Exception oops) { 073 inError = true; 074 addError("Could not create an Appender of type [" + className + "].", oops); 075 throw new ModelHandlerException(oops); 076 } 077 } 078 079 public void postHandle(ModelInterpretationContext mic, Model model) throws ModelHandlerException { 080 if (inError || skipped) { 081 return; 082 } 083 if (appender instanceof LifeCycle) { 084 ((LifeCycle) appender).start(); 085 } 086 mic.markStartOfNamedDependee(appender.getName()); 087 088 Object o = mic.peekObject(); 089 090 @SuppressWarnings("unchecked") 091 Map<String, Appender<E>> appenderBag = (Map<String, Appender<E>>) mic.getObjectMap() 092 .get(JoranConstants.APPENDER_BAG); 093 appenderBag.put(appender.getName(), appender); 094 095 if (o != appender) { 096 addWarn("The object at the of the stack is not the appender named [" + appender.getName() 097 + "] pushed earlier."); 098 } else { 099 mic.popObject(); 100 } 101 102 } 103 104}