Skip to content

Commit 26b9106

Browse files
committed
refactoring Property* related code
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
1 parent 6dc07a2 commit 26b9106

File tree

12 files changed

+410
-82
lines changed

12 files changed

+410
-82
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,106 @@
1-
package ch.qos.logback.classic.tyler;public class TylerConfiguratorBase {
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
4+
*
5+
* This program and the accompanying materials are dual-licensed under
6+
* either the terms of the Eclipse Public License v1.0 as published by
7+
* the Eclipse Foundation
8+
*
9+
* or (per the licensee's choosing)
10+
*
11+
* under the terms of the GNU Lesser General Public License version 2.1
12+
* as published by the Free Software Foundation.
13+
*/
14+
15+
package ch.qos.logback.classic.tyler;
16+
17+
import ch.qos.logback.classic.Level;
18+
import ch.qos.logback.classic.Logger;
19+
import ch.qos.logback.classic.LoggerContext;
20+
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
21+
import ch.qos.logback.core.spi.ContextAwareBase;
22+
import ch.qos.logback.core.spi.PropertyContainer;
23+
import ch.qos.logback.core.spi.ScanException;
24+
import ch.qos.logback.core.status.OnConsoleStatusListener;
25+
import ch.qos.logback.core.util.OptionHelper;
26+
import ch.qos.logback.core.util.StatusListenerConfigHelper;
27+
import ch.qos.logback.core.util.StringUtil;
28+
29+
import java.util.HashMap;
30+
import java.util.Map;
31+
32+
public class TylerConfiguratorBase extends ContextAwareBase implements PropertyContainer {
33+
34+
public static final String SET_CONTEXT_NAME = "setContextName";
35+
public static final String SETUP_LOGGER_METHOD_NAME = "setupLogger";
36+
37+
VariableSubstitutionsHelper variableSubstitutionsHelper;
38+
39+
private Logger setupLogger(String loggerName, Level level, String levelString, Boolean additivity) {
40+
LoggerContext loggerContext = (LoggerContext) context;
41+
Logger logger = loggerContext.getLogger(loggerName);
42+
if (!OptionHelper.isNullOrEmptyOrAllSpaces(levelString)) {
43+
logger.setLevel(level);
44+
}
45+
if (additivity != null) {
46+
logger.setAdditive(additivity);
47+
}
48+
return logger;
49+
}
50+
51+
protected void setContextName(String name) {
52+
if(StringUtil.isNullOrEmpty(name)) {
53+
addError("Cannot set context name to null or empty string");
54+
return;
55+
}
56+
try {
57+
String substName = subst(name);
58+
addInfo("Setting context name to ["+substName+"]");
59+
context.setName(substName);
60+
} catch (IllegalStateException e) {
61+
addError("Failed to rename context as [" + name + "]");
62+
}
63+
}
64+
65+
protected void addOnConsoleStatusListener() {
66+
StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
67+
}
68+
69+
/**
70+
* Performs variable substitution.
71+
*
72+
* @param ref
73+
* @return
74+
*/
75+
public String subst(String ref) {
76+
if (ref == null) {
77+
return null;
78+
}
79+
80+
try {
81+
return OptionHelper.substVars(ref, this, context);
82+
} catch (ScanException | IllegalArgumentException e) {
83+
addError("Problem while parsing [" + ref + "]", e);
84+
return ref;
85+
}
86+
}
87+
88+
@Override
89+
public void addSubstitutionProperty(String key, String value) {
90+
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
91+
}
92+
93+
/**
94+
* If a key is found in propertiesMap then return it.
95+
*/
96+
@Override
97+
public String getProperty(String key) {
98+
return variableSubstitutionsHelper.getProperty(key);
99+
}
100+
101+
@Override
102+
public Map<String, String> getCopyOfPropertyMap() {
103+
return variableSubstitutionsHelper.getCopyOfPropertyMap();
104+
}
105+
2106
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Logback: the reliable, generic, fast and flexible logging framework.
3+
* Copyright (C) 1999-2024, QOS.ch. All rights reserved.
4+
*
5+
* This program and the accompanying materials are dual-licensed under
6+
* either the terms of the Eclipse Public License v1.0 as published by
7+
* the Eclipse Foundation
8+
*
9+
* or (per the licensee's choosing)
10+
*
11+
* under the terms of the GNU Lesser General Public License version 2.1
12+
* as published by the Free Software Foundation.
13+
*/
14+
15+
package ch.qos.logback.classic.tyler;
16+
17+
import ch.qos.logback.core.Context;
18+
import ch.qos.logback.core.joran.action.ActionUtil;
19+
import ch.qos.logback.core.model.ModelConstants;
20+
import ch.qos.logback.core.model.PropertyModel;
21+
import ch.qos.logback.core.model.util.PropertyModelUtil;
22+
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
23+
import ch.qos.logback.core.spi.ContextAwareBase;
24+
import ch.qos.logback.core.util.ContextUtil;
25+
import ch.qos.logback.core.util.Loader;
26+
import ch.qos.logback.core.util.OptionHelper;
27+
28+
import java.io.FileInputStream;
29+
import java.io.FileNotFoundException;
30+
import java.io.IOException;
31+
import java.io.InputStream;
32+
import java.net.URL;
33+
import java.util.Properties;
34+
35+
public class VariableModelHelper extends ContextAwareBase {
36+
37+
TylerConfiguratorBase tylerConfiguratorBase;
38+
VariableSubstitutionsHelper variableSubstitutionsHelper;
39+
40+
VariableModelHelper(Context context, TylerConfiguratorBase tylerConfiguratorBase) {
41+
super( tylerConfiguratorBase);
42+
this.context = context;
43+
this.tylerConfiguratorBase = tylerConfiguratorBase;
44+
this.variableSubstitutionsHelper = new VariableSubstitutionsHelper(context);
45+
}
46+
47+
void updateProperties(PropertyModel propertyModel) {
48+
49+
ActionUtil.Scope scope = ActionUtil.stringToScope(propertyModel.getScopeStr());
50+
if (PropertyModelUtil.checkFileAttributeSanity(propertyModel)) {
51+
String file = propertyModel.getFile();
52+
file = tylerConfiguratorBase.subst(file);
53+
try (FileInputStream istream = new FileInputStream(file)) {
54+
loadAndSetProperties(istream, scope);
55+
} catch (FileNotFoundException e) {
56+
addError("Could not find properties file [" + file + "].");
57+
} catch (IOException |IllegalArgumentException e1) { // IllegalArgumentException is thrown in case the file
58+
// is badly malformed, i.e a binary.
59+
addError("Could not read properties file [" + file + "].", e1);
60+
}
61+
} else if (PropertyModelUtil.checkResourceAttributeSanity(propertyModel)) {
62+
String resource = propertyModel.getResource();
63+
resource = tylerConfiguratorBase.subst(resource);
64+
URL resourceURL = Loader.getResourceBySelfClassLoader(resource);
65+
if (resourceURL == null) {
66+
addError("Could not find resource [" + resource + "].");
67+
} else {
68+
try ( InputStream istream = resourceURL.openStream();) {
69+
loadAndSetProperties(istream, scope);
70+
} catch (IOException e) {
71+
addError("Could not read resource file [" + resource + "].", e);
72+
}
73+
}
74+
} else if (PropertyModelUtil.checkValueNameAttributesSanity(propertyModel)) {
75+
// earlier versions performed Java '\' escapes for '\\' '\t' etc. Howevver, there is no
76+
// need to do this. See RegularEscapeUtil.__UNUSED__basicEscape
77+
String value = propertyModel.getValue();
78+
79+
// now remove both leading and trailing spaces
80+
value = value.trim();
81+
value = tylerConfiguratorBase.subst(value);
82+
setProperty(propertyModel.getName(), value, scope);
83+
84+
} else {
85+
addError(ModelConstants.INVALID_ATTRIBUTES);
86+
}
87+
}
88+
89+
void loadAndSetProperties(InputStream istream, ActionUtil.Scope scope) throws IOException {
90+
Properties props = new Properties();
91+
props.load(istream);
92+
setProperties(props, scope);
93+
}
94+
95+
96+
public void setProperties(Properties props, ActionUtil.Scope scope) {
97+
switch (scope) {
98+
case LOCAL:
99+
variableSubstitutionsHelper.addSubstitutionProperties(props);
100+
break;
101+
case CONTEXT:
102+
ContextUtil cu = new ContextUtil(getContext());
103+
cu.addProperties(props);
104+
break;
105+
case SYSTEM:
106+
OptionHelper.setSystemProperties(this, props);
107+
}
108+
}
109+
110+
public void setProperty(String key, String value, ActionUtil.Scope scope) {
111+
switch (scope) {
112+
case LOCAL:
113+
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
114+
break;
115+
case CONTEXT:
116+
getContext().putProperty(key, value);
117+
break;
118+
case SYSTEM:
119+
OptionHelper.setSystemProperty(this, key, value);
120+
}
121+
}
122+
}

logback-classic/src/test/java/ch/qos/logback/classic/sift/SiftingAppenderTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import ch.qos.logback.core.testUtil.StringListAppender;
4444
import ch.qos.logback.core.util.FileSize;
45+
import ch.qos.logback.core.util.StatusPrinter;
4546
import org.junit.jupiter.api.AfterEach;
4647
import org.junit.jupiter.api.BeforeEach;
4748
import org.junit.jupiter.api.Disabled;
@@ -244,6 +245,7 @@ public void localPropertiesShouldBeVisible() throws JoranException {
244245
SiftingAppender sa = (SiftingAppender) root.getAppender("SIFT");
245246
StringListAppender<ILoggingEvent> listAppender = (StringListAppender<ILoggingEvent>) sa.getAppenderTracker().find(mdcVal);
246247
assertNotNull(listAppender);
248+
247249
List<String> strList = listAppender.strList;
248250
assertEquals(1, listAppender.strList.size());
249251
assertEquals(prefix + msg, strList.get(0));

logback-core/src/main/java/ch/qos/logback/core/ContextBase.java

+10
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ protected void initCollisionMaps() {
107107
putObject(RFA_FILENAME_PATTERN_COLLISION_MAP, new HashMap<String, FileNamePattern>());
108108
}
109109

110+
@Override
111+
public void addSubstitutionProperty(String key, String value) {
112+
if (key == null || value == null) {
113+
return;
114+
}
115+
// values with leading or trailing spaces are bad. We remove them now.
116+
value = value.trim();
117+
propertyMap.put(key, value);
118+
}
119+
110120
/**
111121
* Given a key, return the corresponding property value. If invoked with the
112122
* special key "CONTEXT_NAME", the name of the context is returned.

logback-core/src/main/java/ch/qos/logback/core/joran/spi/SaxEventInterpretationContext.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ public Stack<Model> getCopyOfModelStack() {
7777
return copy;
7878
}
7979

80+
public void addSubstitutionProperty(String key, String value) {
81+
throw new UnsupportedOperationException();
82+
}
83+
8084
/**
8185
* If a key is found in propertiesMap then return it. Otherwise, delegate to the
8286
* context.
@@ -85,7 +89,6 @@ public String getProperty(String key) {
8589
return context.getProperty(key);
8690
}
8791

88-
@Override
8992
public Map<String, String> getCopyOfPropertyMap() {
9093
return null;
9194
}

logback-core/src/main/java/ch/qos/logback/core/model/ModelConstants.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@ public class ModelConstants {
2020

2121
public static final String DEBUG_SYSTEM_PROPERTY_KEY = "logback.debug";
2222
public static final String NULL_STR = CoreConstants.NULL_STR;
23-
23+
24+
public static final String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or "
25+
+ "the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";
26+
2427
}

logback-core/src/main/java/ch/qos/logback/core/model/processor/ModelInterpretationContext.java

+9-41
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,18 @@
2727
import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
2828
import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
2929
import ch.qos.logback.core.model.Model;
30+
import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
3031
import ch.qos.logback.core.spi.AppenderAttachable;
3132
import ch.qos.logback.core.spi.ContextAwareBase;
3233
import ch.qos.logback.core.spi.PropertyContainer;
33-
import ch.qos.logback.core.spi.ScanException;
34-
import ch.qos.logback.core.util.OptionHelper;
3534

3635
public class ModelInterpretationContext extends ContextAwareBase implements PropertyContainer {
3736

3837
Stack<Object> objectStack;
3938
Stack<Model> modelStack;
4039

4140
Map<String, Object> objectMap;
42-
protected Map<String, String> propertiesMap;
41+
protected VariableSubstitutionsHelper variableSubstitutionsHelper;
4342
protected Map<String, String> importMap;
4443

4544
final private BeanDescriptionCache beanDescriptionCache;
@@ -62,14 +61,14 @@ public ModelInterpretationContext(Context context, Object configuratorHint) {
6261
this.modelStack = new Stack<>();
6362
this.beanDescriptionCache = new BeanDescriptionCache(context);
6463
objectMap = new HashMap<>(5);
65-
propertiesMap = new HashMap<>(5);
64+
variableSubstitutionsHelper = new VariableSubstitutionsHelper(context);
6665
importMap = new HashMap<>(5);
6766
}
6867

6968
public ModelInterpretationContext(ModelInterpretationContext otherMic) {
7069
this(otherMic.context, otherMic.configuratorHint);
7170
importMap = new HashMap<>(otherMic.importMap);
72-
propertiesMap = new HashMap<>(otherMic.propertiesMap);
71+
variableSubstitutionsHelper = new VariableSubstitutionsHelper(context, otherMic.getCopyOfPropertyMap());
7372
defaultNestedComponentRegistry.duplicate(otherMic.getDefaultNestedComponentRegistry());
7473
createAppenderBags();
7574
}
@@ -149,42 +148,16 @@ public BeanDescriptionCache getBeanDescriptionCache() {
149148
return beanDescriptionCache;
150149
}
151150

152-
public String subst(String ref) {
153-
if (ref == null) {
154-
return null;
155-
}
156-
157-
try {
158-
return OptionHelper.substVars(ref, this, context);
159-
} catch (ScanException | IllegalArgumentException e) {
160-
addError("Problem while parsing [" + ref + "]", e);
161-
return ref;
162-
}
163-
151+
public String subst(String ref) {
152+
return variableSubstitutionsHelper.subst(ref);
164153
}
165154

166155
/**
167156
* Add a property to the properties of this execution context. If the property
168157
* exists already, it is overwritten.
169158
*/
170159
public void addSubstitutionProperty(String key, String value) {
171-
if (key == null || value == null) {
172-
return;
173-
}
174-
// values with leading or trailing spaces are bad. We remove them now.
175-
value = value.trim();
176-
propertiesMap.put(key, value);
177-
}
178-
179-
public void addSubstitutionProperties(Properties props) {
180-
if (props == null) {
181-
return;
182-
}
183-
for (Object keyObject : props.keySet()) {
184-
String key = (String) keyObject;
185-
String val = props.getProperty(key);
186-
addSubstitutionProperty(key, val);
187-
}
160+
variableSubstitutionsHelper.addSubstitutionProperty(key, value);
188161
}
189162

190163
public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
@@ -241,17 +214,12 @@ public boolean isNamedDependeeStarted(String name) {
241214
* context.
242215
*/
243216
public String getProperty(String key) {
244-
String v = propertiesMap.get(key);
245-
if (v != null) {
246-
return v;
247-
} else {
248-
return context.getProperty(key);
249-
}
217+
return variableSubstitutionsHelper.getProperty(key);
250218
}
251219

252220
@Override
253221
public Map<String, String> getCopyOfPropertyMap() {
254-
return new HashMap<String, String>(propertiesMap);
222+
return variableSubstitutionsHelper.getCopyOfPropertyMap();
255223
}
256224

257225
// imports

0 commit comments

Comments
 (0)