Skip to content

Commit

Permalink
refactoring Property* related code
Browse files Browse the repository at this point in the history
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
  • Loading branch information
ceki committed Feb 26, 2024
1 parent 6dc07a2 commit 26b9106
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,106 @@
package ch.qos.logback.classic.tyler;public class TylerConfiguratorBase {
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/

package ch.qos.logback.classic.tyler;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.PropertyContainer;
import ch.qos.logback.core.spi.ScanException;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.util.OptionHelper;
import ch.qos.logback.core.util.StatusListenerConfigHelper;
import ch.qos.logback.core.util.StringUtil;

import java.util.HashMap;
import java.util.Map;

public class TylerConfiguratorBase extends ContextAwareBase implements PropertyContainer {

public static final String SET_CONTEXT_NAME = "setContextName";
public static final String SETUP_LOGGER_METHOD_NAME = "setupLogger";

VariableSubstitutionsHelper variableSubstitutionsHelper;

private Logger setupLogger(String loggerName, Level level, String levelString, Boolean additivity) {
LoggerContext loggerContext = (LoggerContext) context;
Logger logger = loggerContext.getLogger(loggerName);
if (!OptionHelper.isNullOrEmptyOrAllSpaces(levelString)) {
logger.setLevel(level);
}
if (additivity != null) {
logger.setAdditive(additivity);
}
return logger;
}

protected void setContextName(String 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+"]");
context.setName(substName);
} catch (IllegalStateException e) {
addError("Failed to rename context as [" + name + "]");
}
}

protected void addOnConsoleStatusListener() {
StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
}

/**
* Performs variable substitution.
*
* @param ref
* @return
*/
public String subst(String ref) {
if (ref == null) {
return null;
}

try {
return OptionHelper.substVars(ref, this, context);
} catch (ScanException | IllegalArgumentException e) {
addError("Problem while parsing [" + ref + "]", e);
return ref;
}
}

@Override
public void addSubstitutionProperty(String key, String value) {
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
}

/**
* If a key is found in propertiesMap then return it.
*/
@Override
public String getProperty(String key) {
return variableSubstitutionsHelper.getProperty(key);
}

@Override
public Map<String, String> getCopyOfPropertyMap() {
return variableSubstitutionsHelper.getCopyOfPropertyMap();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/

package ch.qos.logback.classic.tyler;

import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.action.ActionUtil;
import ch.qos.logback.core.model.ModelConstants;
import ch.qos.logback.core.model.PropertyModel;
import ch.qos.logback.core.model.util.PropertyModelUtil;
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.ContextUtil;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

public class VariableModelHelper extends ContextAwareBase {

TylerConfiguratorBase tylerConfiguratorBase;
VariableSubstitutionsHelper variableSubstitutionsHelper;

VariableModelHelper(Context context, TylerConfiguratorBase tylerConfiguratorBase) {
super( tylerConfiguratorBase);
this.context = context;
this.tylerConfiguratorBase = tylerConfiguratorBase;
this.variableSubstitutionsHelper = new VariableSubstitutionsHelper(context);
}

void updateProperties(PropertyModel propertyModel) {

ActionUtil.Scope scope = ActionUtil.stringToScope(propertyModel.getScopeStr());
if (PropertyModelUtil.checkFileAttributeSanity(propertyModel)) {
String file = propertyModel.getFile();
file = tylerConfiguratorBase.subst(file);
try (FileInputStream istream = new FileInputStream(file)) {
loadAndSetProperties(istream, scope);
} catch (FileNotFoundException e) {
addError("Could not find properties file [" + file + "].");
} catch (IOException |IllegalArgumentException e1) { // IllegalArgumentException is thrown in case the file
// is badly malformed, i.e a binary.
addError("Could not read properties file [" + file + "].", e1);
}
} else if (PropertyModelUtil.checkResourceAttributeSanity(propertyModel)) {
String resource = propertyModel.getResource();
resource = tylerConfiguratorBase.subst(resource);
URL resourceURL = Loader.getResourceBySelfClassLoader(resource);
if (resourceURL == null) {
addError("Could not find resource [" + resource + "].");
} else {
try ( InputStream istream = resourceURL.openStream();) {
loadAndSetProperties(istream, scope);
} catch (IOException e) {
addError("Could not read resource file [" + resource + "].", e);
}
}
} else if (PropertyModelUtil.checkValueNameAttributesSanity(propertyModel)) {
// earlier versions performed Java '\' escapes for '\\' '\t' etc. Howevver, there is no
// need to do this. See RegularEscapeUtil.__UNUSED__basicEscape
String value = propertyModel.getValue();

// now remove both leading and trailing spaces
value = value.trim();
value = tylerConfiguratorBase.subst(value);
setProperty(propertyModel.getName(), value, scope);

} else {
addError(ModelConstants.INVALID_ATTRIBUTES);
}
}

void loadAndSetProperties(InputStream istream, ActionUtil.Scope scope) throws IOException {
Properties props = new Properties();
props.load(istream);
setProperties(props, scope);
}


public void setProperties(Properties props, ActionUtil.Scope scope) {
switch (scope) {
case LOCAL:
variableSubstitutionsHelper.addSubstitutionProperties(props);
break;
case CONTEXT:
ContextUtil cu = new ContextUtil(getContext());
cu.addProperties(props);
break;
case SYSTEM:
OptionHelper.setSystemProperties(this, props);
}
}

public void setProperty(String key, String value, ActionUtil.Scope scope) {
switch (scope) {
case LOCAL:
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
break;
case CONTEXT:
getContext().putProperty(key, value);
break;
case SYSTEM:
OptionHelper.setSystemProperty(this, key, value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

import ch.qos.logback.core.testUtil.StringListAppender;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.StatusPrinter;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
Expand Down Expand Up @@ -244,6 +245,7 @@ public void localPropertiesShouldBeVisible() throws JoranException {
SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa.getAppenderTracker().find(mdcVal);
assertNotNull(listAppender);

List<String> strList = listAppender.strList;
assertEquals(1, listAppender.strList.size());
assertEquals(prefix + msg, strList.get(0));
Expand Down
10 changes: 10 additions & 0 deletions logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ protected void initCollisionMaps() {
putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
}

@Override
public void addSubstitutionProperty(String key, String value) {
if (key == null || value == null) {
return;
}
// values with leading or trailing spaces are bad. We remove them now.
value = value.trim();
propertyMap.put(key, value);
}

/**
* Given a key, return the corresponding property value. If invoked with the
* special key "CONTEXT_NAME", the name of the context is returned.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public Stack<Model> getCopyOfModelStack() {
return copy;
}

public void addSubstitutionProperty(String key, String value) {
throw new UnsupportedOperationException();
}

/**
* If a key is found in propertiesMap then return it. Otherwise, delegate to the
* context.
Expand All @@ -85,7 +89,6 @@ public String getProperty(String key) {
return context.getProperty(key);
}

@Override
public Map<String, String> getCopyOfPropertyMap() {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ public class ModelConstants {

public static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback.debug";
public static final String NULL_STR = CoreConstants.NULL_STR;


public static final String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or "
+ "the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,18 @@
import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.model.Model;
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
import ch.qos.logback.core.spi.AppenderAttachable;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.PropertyContainer;
import ch.qos.logback.core.spi.ScanException;
import ch.qos.logback.core.util.OptionHelper;

public class ModelInterpretationContext extends ContextAwareBase implements PropertyContainer {

Stack<Object> objectStack;
Stack<Model> modelStack;

Map<String, Object> objectMap;
protected Map<String, String> propertiesMap;
protected VariableSubstitutionsHelper variableSubstitutionsHelper;
protected Map<String, String> importMap;

final private BeanDescriptionCache beanDescriptionCache;
Expand All @@ -62,14 +61,14 @@ public ModelInterpretationContext(Context context, Object configuratorHint) {
this.modelStack = new Stack<>();
this.beanDescriptionCache = new BeanDescriptionCache(context);
objectMap = new HashMap<>(5);
propertiesMap = new HashMap<>(5);
variableSubstitutionsHelper = new VariableSubstitutionsHelper(context);
importMap = new HashMap<>(5);
}

public ModelInterpretationContext(ModelInterpretationContext otherMic) {
this(otherMic.context, otherMic.configuratorHint);
importMap = new HashMap<>(otherMic.importMap);
propertiesMap = new HashMap<>(otherMic.propertiesMap);
variableSubstitutionsHelper = new VariableSubstitutionsHelper(context, otherMic.getCopyOfPropertyMap());
defaultNestedComponentRegistry.duplicate(otherMic.getDefaultNestedComponentRegistry());
createAppenderBags();
}
Expand Down Expand Up @@ -149,42 +148,16 @@ public BeanDescriptionCache getBeanDescriptionCache() {
return beanDescriptionCache;
}

public String subst(String ref) {
if (ref == null) {
return null;
}

try {
return OptionHelper.substVars(ref, this, context);
} catch (ScanException | IllegalArgumentException e) {
addError("Problem while parsing [" + ref + "]", e);
return ref;
}

public String subst(String ref) {
return variableSubstitutionsHelper.subst(ref);
}

/**
* Add a property to the properties of this execution context. If the property
* exists already, it is overwritten.
*/
public void addSubstitutionProperty(String key, String value) {
if (key == null || value == null) {
return;
}
// values with leading or trailing spaces are bad. We remove them now.
value = value.trim();
propertiesMap.put(key, value);
}

public void addSubstitutionProperties(Properties props) {
if (props == null) {
return;
}
for (Object keyObject : props.keySet()) {
String key = (String) keyObject;
String val = props.getProperty(key);
addSubstitutionProperty(key, val);
}
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
}

public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
Expand Down Expand Up @@ -241,17 +214,12 @@ public boolean isNamedDependeeStarted(String name) {
* context.
*/
public String getProperty(String key) {
String v = propertiesMap.get(key);
if (v != null) {
return v;
} else {
return context.getProperty(key);
}
return variableSubstitutionsHelper.getProperty(key);
}

@Override
public Map<String, String> getCopyOfPropertyMap() {
return new HashMap<String, String>(propertiesMap);
return variableSubstitutionsHelper.getCopyOfPropertyMap();
}

// imports
Expand Down
Loading

0 comments on commit 26b9106

Please sign in to comment.