Skip to content

Commit

Permalink
refactorings in support of logback-tyler
Browse files Browse the repository at this point in the history
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
  • Loading branch information
ceki committed Oct 14, 2024
1 parent 8749edc commit 75bee86
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.model.ConfigurationModel;
import ch.qos.logback.classic.util.LevelUtil;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.GenericXMLConfigurator;
import ch.qos.logback.core.model.Model;
import ch.qos.logback.core.model.util.PropertyModelHandlerHelper;
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
import ch.qos.logback.core.spi.ContextAwareBase;
Expand All @@ -29,6 +33,7 @@
import ch.qos.logback.core.util.StringUtil;

import java.util.Map;
import java.util.function.Supplier;

public class TylerConfiguratorBase extends ContextAwareBase implements ContextAwarePropertyContainer {

Expand Down Expand Up @@ -64,13 +69,13 @@ public void setContext(Context context) {
}

protected void setContextName(String name) {
if(StringUtil.isNullOrEmpty(name)) {
if (StringUtil.isNullOrEmpty(name)) {
addError("Cannot set context name to null or empty string");
return;
}
try {
String substName = subst(name);
addInfo("Setting context name to ["+substName+"]");
addInfo("Setting context name to [" + substName + "]");
context.setName(substName);
} catch (IllegalStateException e) {
addError("Failed to rename context as [" + name + "]");
Expand Down Expand Up @@ -153,4 +158,29 @@ public String property(String k) {
else
return "";
}

private JoranConfigurator makeAnotherInstance() {
JoranConfigurator jc = new JoranConfigurator();
jc.setContext(context);
return jc;
}

/**
* Return a supplier which supplies an instance of {@link JoranConfigurator} set to
* the same context the context of 'this'.
* @since 1.5.11
*/
@Override
public Supplier<? extends GenericXMLConfigurator> getConfiguratorSupplier() {
Supplier<? extends GenericXMLConfigurator> supplier = () -> this.makeAnotherInstance();
return supplier;
}

protected void processModelFromIncludedFile(Model modelFromIncludedFile) {
Supplier<? extends GenericXMLConfigurator > configuratorSupplier = this.getConfiguratorSupplier();
GenericXMLConfigurator genericXMLConfigurator = configuratorSupplier.get();
ConfigurationModel configururationModel = new ConfigurationModel();
configururationModel.addSubModel(modelFromIncludedFile);
genericXMLConfigurator.processModel(configururationModel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import ch.qos.logback.core.model.IncludeModel;
import ch.qos.logback.core.model.Model;
import ch.qos.logback.core.spi.ContextAwarePropertyContainer;
import ch.qos.logback.core.spi.ErrorCodes;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
Expand Down Expand Up @@ -60,18 +61,35 @@ protected Class<IncludeModel> getSupportedModelClass() {
@Override
public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
IncludeModel includeModel = (IncludeModel) model;
Model modelFromIncludedFile = buildModelFromIncludedFile(mic, includeModel);
if (modelFromIncludedFile == null) {
warnIfRequired("Failed to build include model from included file");
return;
}
processModelFromIncludedFile(includeModel, modelFromIncludedFile);
}

/**
* This method is called by logback-tyler at TylerConfigurator run-time.
*
* @param capc
* @param includeModel
* @throws ModelHandlerException
* @since 1.5.11
*/
public Model buildModelFromIncludedFile(ContextAwarePropertyContainer capc, IncludeModel includeModel) throws ModelHandlerException {

this.optional = OptionHelper.toBoolean(includeModel.getOptional(), false);

if (!checkAttributes(includeModel)) {
inError = true;
return;
return null;
}

InputStream in = getInputStream(mic, includeModel);
if(in == null) {
InputStream in = getInputStream(capc, includeModel);
if (in == null) {
inError = true;
return;
return null;
}

SaxEventRecorder recorder = null;
Expand All @@ -82,41 +100,40 @@ public void handle(ModelInterpretationContext mic, Model model) throws ModelHand
List<SaxEvent> saxEvents = recorder.getSaxEventList();
if (saxEvents.isEmpty()) {
addWarn("Empty sax event list");
return;
return null;
}

Supplier<? extends GenericXMLConfigurator> jcSupplier = mic.getConfiguratorSupplier();
Supplier<? extends GenericXMLConfigurator> jcSupplier = capc.getConfiguratorSupplier();
if (jcSupplier == null) {
addError("null configurator supplier. Abandoning inclusion of [" + attributeInUse + "]");
inError = true;
return;
return null;
}

GenericXMLConfigurator genericXMLConfigurator = jcSupplier.get();
genericXMLConfigurator.getRuleStore().addPathPathMapping(INCLUDED_TAG, CONFIGURATION_TAG);

Model modelFromIncludedFile = genericXMLConfigurator.buildModelFromSaxEventList(recorder.getSaxEventList());
if (modelFromIncludedFile == null) {
addError(ErrorCodes.EMPTY_MODEL_STACK);
return;
}

includeModel.getSubModels().addAll(modelFromIncludedFile.getSubModels());

return modelFromIncludedFile;
} catch (JoranException e) {
inError = true;
addError("Error processing XML data in [" + attributeInUse + "]", e);
return null;
}
}

private void processModelFromIncludedFile(IncludeModel includeModel, Model modelFromIncludedFile) {
includeModel.getSubModels().addAll(modelFromIncludedFile.getSubModels());
}

public SaxEventRecorder populateSaxEventRecorder(final InputStream inputStream) throws JoranException {
SaxEventRecorder recorder = new SaxEventRecorder(context);
recorder.recordEvents(inputStream);
return recorder;
}

private InputStream getInputStream(ModelInterpretationContext mic, IncludeModel includeModel) {
URL inputURL = getInputURL(mic, includeModel);
private InputStream getInputStream(ContextAwarePropertyContainer capc, IncludeModel includeModel) {
URL inputURL = getInputURL(capc, includeModel);
if (inputURL == null)
return null;
ConfigurationWatchListUtil.addToWatchList(context, inputURL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ public String getImport(String stem) {
*
* @return a supplier of {@link GenericXMLConfigurator} instance, may be null
*/
@Override
public Supplier<? extends GenericXMLConfigurator> getConfiguratorSupplier() {
return this.configuratorSupplier;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

package ch.qos.logback.core.spi;

import ch.qos.logback.core.joran.GenericXMLConfigurator;

import java.util.function.Supplier;

/**
* An interface extending both {@link PropertyContainer} and {@link ContextAware}
*
Expand All @@ -30,4 +34,17 @@ public interface ContextAwarePropertyContainer extends PropertyContainer, Contex
*/
String subst(String input);


/**
* Returns a supplier of {@link GenericXMLConfigurator} instance. The returned value may be null.
*
* <p>This method could/should have been part of a new interface. It is added here for reasons
* of commodity and not coherence.</p>
*
* @return a supplier of {@link GenericXMLConfigurator} instance, may be null
* @since 1.5.11
*/
default public Supplier<? extends GenericXMLConfigurator> getConfiguratorSupplier() {
return null;
}
}

0 comments on commit 75bee86

Please sign in to comment.