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.joran.action; 015 016import org.xml.sax.Attributes; 017 018import ch.qos.logback.core.joran.spi.ActionException; 019import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext; 020import ch.qos.logback.core.model.Model; 021 022public abstract class BaseModelAction extends Action { 023 024 Model parentModel; 025 Model currentModel; 026 boolean inError = false; 027 028 @Override 029 public void begin(SaxEventInterpretationContext saxEventInterpretationContext, String name, Attributes attributes) 030 throws ActionException { 031 parentModel = null; 032 inError = false; 033 034 if (!validPreconditions(saxEventInterpretationContext, name, attributes)) { 035 inError = true; 036 return; 037 } 038 039 currentModel = buildCurrentModel(saxEventInterpretationContext, name, attributes); 040 currentModel.setTag(name); 041 if (!saxEventInterpretationContext.isModelStackEmpty()) { 042 parentModel = saxEventInterpretationContext.peekModel(); 043 } 044 final int lineNumber = getLineNumber(saxEventInterpretationContext); 045 currentModel.setLineNumber(lineNumber); 046 saxEventInterpretationContext.pushModel(currentModel); 047 } 048 049 abstract protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name, 050 Attributes attributes); 051 052 /** 053 * Validate preconditions of this action. 054 * 055 * By default, true is returned. Subclasses should override appropriately. 056 * 057 * @param intercon 058 * @param name 059 * @param attributes 060 * @return 061 */ 062 protected boolean validPreconditions(SaxEventInterpretationContext intercon, String name, Attributes attributes) { 063 return true; 064 } 065 066 @Override 067 public void body(SaxEventInterpretationContext ec, String body) throws ActionException { 068 if(currentModel == null) { 069 throw new ActionException("current model is null. Is <configuration> element missing?"); 070 } 071 currentModel.addText(body); 072 } 073 074 @Override 075 public void end(SaxEventInterpretationContext saxEventInterpretationContext, String name) throws ActionException { 076 if (inError) 077 return; 078 079 Model m = saxEventInterpretationContext.peekModel(); 080 081 if (m != currentModel) { 082 addWarn("The object "+ m +"] at the top of the stack differs from the model [" + currentModel.idString() 083 + "] pushed earlier."); 084 addWarn("This is wholly unexpected."); 085 } 086 087 // do not pop nor add to parent if there is no parent 088 if (parentModel != null) { 089 parentModel.addSubModel(currentModel); 090 saxEventInterpretationContext.popModel(); 091 } 092 } 093}