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 */
027package ch.qos.logback.tyler.base;
028
029import ch.qos.logback.classic.joran.JoranConfigurator;
030import ch.qos.logback.classic.model.ConfigurationModel;
031import ch.qos.logback.classic.model.ContextNameModel;
032import ch.qos.logback.classic.model.LoggerModel;
033import ch.qos.logback.classic.model.RootLoggerModel;
034import ch.qos.logback.classic.model.processor.LogbackClassicDefaultNestedComponentRules;
035import ch.qos.logback.core.Context;
036import ch.qos.logback.core.joran.event.SaxEventRecorder;
037import ch.qos.logback.core.joran.spi.JoranException;
038import ch.qos.logback.core.model.AppenderModel;
039import ch.qos.logback.core.model.AppenderRefModel;
040import ch.qos.logback.core.model.ImplicitModel;
041import ch.qos.logback.core.model.ImportModel;
042import ch.qos.logback.core.model.Model;
043import ch.qos.logback.core.model.PropertyModel;
044import ch.qos.logback.core.model.processor.DefaultProcessor;
045import ch.qos.logback.core.model.processor.ImportModelHandler;
046import ch.qos.logback.tyler.base.handler.AppenderRefModelHandler;
047import ch.qos.logback.tyler.base.handler.ContextNameModelHandler;
048
049import ch.qos.logback.tyler.base.handler.AppenderModelHandler;
050import ch.qos.logback.tyler.base.handler.ConfigurationModelHandler;
051import ch.qos.logback.tyler.base.handler.ImplicitModelHandler;
052import ch.qos.logback.tyler.base.handler.LoggerModelHandler;
053import ch.qos.logback.tyler.base.handler.RootLoggerModelHandler;
054import ch.qos.logback.tyler.base.handler.VariableModelHandler;
055import com.squareup.javapoet.JavaFile;
056import com.squareup.javapoet.MethodSpec;
057import com.squareup.javapoet.TypeSpec;
058import org.xml.sax.InputSource;
059
060import java.io.ByteArrayInputStream;
061import java.io.IOException;
062import java.io.InputStream;
063
064public class ModelToJava {
065
066
067    Context context;
068
069    ModelToJava(Context context) {
070        this.context = context;
071    }
072
073    Model extractModel(String input) throws JoranException {
074        InputStream inputStream = new ByteArrayInputStream(input.getBytes());
075        InputSource inputSource = new InputSource(inputStream);
076        inputSource.setSystemId("UNKNOWN");
077
078        JoranConfigurator joranConfigurator = new JoranConfigurator();
079        joranConfigurator.setContext(context);
080
081        SaxEventRecorder recorder = joranConfigurator.populateSaxEventRecorder(inputSource);
082        Model top = joranConfigurator.buildModelFromSaxEventList(recorder.getSaxEventList());
083        return top;
084    }
085
086    public String toJava(Model topModel) throws IOException {
087        TylerModelInterpretationContext tmic = new TylerModelInterpretationContext(context);
088        tmic.setTopModel(topModel);
089
090        LogbackClassicDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(tmic.getDefaultNestedComponentRegistry());
091
092        DefaultProcessor defaultProcessor = new DefaultProcessor(context, tmic);
093        addModelHandlerAssociations(defaultProcessor);
094
095        defaultProcessor.process(topModel);
096
097
098        tmic.configureMethodSpecBuilder.addStatement("return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY");
099        MethodSpec configureMethodSpec = tmic.configureMethodSpecBuilder.build();
100
101        tmic.tylerConfiguratorTSB.methodSpecs.addFirst(configureMethodSpec);
102
103
104        TypeSpec tylerConfiguratorTypeSpec = tmic.tylerConfiguratorTSB.build();
105        JavaFile javaFile = JavaFile.builder("com.example.helloworld", tylerConfiguratorTypeSpec)
106                .indent("    ")
107                .build();
108        //StringBuilder sb = new StringBuilder();
109        StringBuffer sb = new StringBuffer();
110        javaFile.writeTo(sb);
111        return sb.toString();
112    }
113
114    private void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
115        defaultProcessor.addHandler(ConfigurationModel.class, ConfigurationModelHandler::makeInstance);
116
117        defaultProcessor.addHandler(PropertyModel.class, VariableModelHandler::makeInstance);
118
119
120        defaultProcessor.addHandler(ContextNameModel.class, ContextNameModelHandler::makeInstance);
121        defaultProcessor.addHandler(ImportModel.class, ImportModelHandler::makeInstance);
122        defaultProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance);
123        defaultProcessor.addHandler(ImplicitModel.class, ImplicitModelHandler::makeInstance);
124        defaultProcessor.addHandler(LoggerModel.class, LoggerModelHandler::makeInstance);
125        defaultProcessor.addHandler(RootLoggerModel.class, RootLoggerModelHandler::makeInstance);
126
127        defaultProcessor.addHandler(AppenderRefModel.class, AppenderRefModelHandler::makeInstance);
128    }
129
130}