001 /* 002 * Copyright (c) 2024 QOS.ch Sarl (Switzerland) 003 * All rights reserved. 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining 006 * a copy of this software and associated documentation files (the 007 * "Software"), to deal in the Software without restriction, including 008 * without limitation the rights to use, copy, modify, merge, publish, 009 * distribute, sublicense, and/or sell copies of the Software, and to 010 * permit persons to whom the Software is furnished to do so, subject to 011 * the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be 014 * included in all copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 023 * 024 * 025 * 026 */ 027 028 package ch.qos.logback.tyler.base; 029 030 import ch.qos.logback.classic.Level; 031 import ch.qos.logback.classic.LoggerContext; 032 import ch.qos.logback.classic.spi.Configurator; 033 import ch.qos.logback.classic.tyler.TylerConfiguratorBase; 034 import ch.qos.logback.classic.util.ContextInitializer; 035 import ch.qos.logback.core.Context; 036 import ch.qos.logback.core.model.processor.ModelInterpretationContext; 037 import com.squareup.javapoet.FieldSpec; 038 import com.squareup.javapoet.MethodSpec; 039 import com.squareup.javapoet.ParameterSpec; 040 import com.squareup.javapoet.TypeSpec; 041 042 import javax.lang.model.element.Modifier; 043 044 import static ch.qos.logback.tyler.base.TylerConstants.CONFIGURE_METHOD_NAME; 045 import static ch.qos.logback.tyler.base.TylerConstants.CONTEXT_FIELD_NAME; 046 import static ch.qos.logback.tyler.base.TylerConstants.LEVEL_FIELD_NAME; 047 import static ch.qos.logback.tyler.base.TylerConstants.LOGGER_CONTEXT_PARAMETER_NAME; 048 import static ch.qos.logback.tyler.base.TylerConstants.REQUIRED_LOGBACK_VERSION; 049 050 public class TylerModelInterpretationContext extends ModelInterpretationContext { 051 052 053 final public TypeSpec.Builder tylerConfiguratorTSB; 054 final public MethodSpec.Builder configureMethodSpecBuilder; 055 056 057 final FieldSpec contextFieldSpec = FieldSpec.builder(LoggerContext.class, CONTEXT_FIELD_NAME, Modifier.PRIVATE).build(); 058 final ParameterSpec contextParameterSpec = ParameterSpec.builder(LoggerContext.class, LOGGER_CONTEXT_PARAMETER_NAME).build(); 059 final ParameterSpec levelParameterSpec = ParameterSpec.builder(Level.class, LEVEL_FIELD_NAME).build(); 060 061 public TylerModelInterpretationContext(Context context) { 062 super(context); 063 this.configureMethodSpecBuilder = initializeConfigureMethodSpecBuilder(); 064 this.tylerConfiguratorTSB = initializeTylerConfiguratorTSB(); 065 } 066 067 068 TypeSpec.Builder initializeTylerConfiguratorTSB() { 069 //MethodSpec setupLoggerMS = makeSetupLoggerMethodSpec(); 070 071 TypeSpec.Builder tsb = TypeSpec.classBuilder(TylerConstants.TYLER_CONFIGURATOR) 072 .addJavadoc(""" 073 <p>BEWARE: As of March 2024, TylerConfigurator generation from logback.xml configuration files is 074 still experimental and incomplete. 075 <p> 076 077 <p>This class, i.e. TylerConfigurator, is intended to be copied and integrated into the user's 078 project as custom configurator. It will configure logback without XML.</p> 079 080 <p>It requires logback-classic version %s or later at runtime.</p> 081 082 <p>Custom configurators are looked up via Java's service-provide facility. If a custom provider is 083 found, it takes precedence over logback's own configurators, e.g. DefaultJoranConfigurator.</p> 084 085 <p>See also item 1 of 'Configuration at initialization' section at 086 "https://logback.qos.ch/manual/configuration.html#auto_configuration </p> 087 """.formatted(REQUIRED_LOGBACK_VERSION)) 088 .addSuperinterface(Configurator.class) 089 .superclass(TylerConfiguratorBase.class); 090 return tsb; 091 } 092 093 private MethodSpec.Builder initializeConfigureMethodSpecBuilder() { 094 MethodSpec.Builder msb = MethodSpec.methodBuilder(CONFIGURE_METHOD_NAME) 095 .addJavadoc(""" 096 <p>This method performs configuration per {@link $T} interface.</p> 097 098 <p>If <code>TylerConfgiurator</code> is installed as a configurator service, this method will be 099 called by logback-classic during initialization.</p> 100 """, Configurator.class) 101 .addAnnotation(Override.class) 102 .addModifiers(Modifier.PUBLIC) 103 .addParameter(contextParameterSpec) 104 .returns(Configurator.ExecutionStatus.class) 105 .addStatement("$N($N)", TylerConfiguratorBase.SET_CONTEXT_METHOD_NAME, contextParameterSpec); 106 107 return msb; 108 } 109 110// private MethodSpec makeSetupLoggerMethodSpec() { 111// MethodSpec.Builder msb = MethodSpec.methodBuilder(SETUP_LOGGER_METHOD_NAME) 112// .addModifiers(Modifier.PRIVATE) 113// .addParameter(String.class, LOGGER_NAME_FIELD_NAME) 114// .addParameter(levelParameterSpec) 115// .addParameter(String.class, LEVEL_STRING_PARAMETER_NAME) 116// .addParameter(Boolean.class, ADDITIVITY_FIELD_NAME) 117// .returns(Logger.class) 118// .addStatement("$1T loggerContext = ($1T) $2N", LoggerContext.class, CONTEXT_FIELD_NAME) 119// .addStatement("$T $N = loggerContext.getLogger($N)", Logger.class, LOGGER_FIELD_NAME, LOGGER_NAME_FIELD_NAME) 120// .beginControlFlow("if (!$T.isNullOrEmptyOrAllSpaces($N))", OptionHelper.class, LEVEL_STRING_PARAMETER_NAME) 121// .addStatement("$N.setLevel($N)", LOGGER_FIELD_NAME, LEVEL_FIELD_NAME) 122// .endControlFlow() 123// .beginControlFlow("if ($N != null)", ADDITIVITY_FIELD_NAME) 124// .addStatement("$N.setAdditive($N)", LOGGER_FIELD_NAME, ADDITIVITY_FIELD_NAME) 125// .endControlFlow() 126// .addStatement("return $N", LOGGER_FIELD_NAME); 127// 128// return msb.build(); 129// } 130 131 public FieldSpec getContextFieldSpec() { 132 return contextFieldSpec; 133 } 134 }