1 /*
2 * Logback: the reliable, generic, fast and flexible logging framework.
3 * Copyright (C) 1999-2026, 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 v2.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.core.boolex;
16
17 import ch.qos.logback.core.model.processor.ModelInterpretationContext;
18 import ch.qos.logback.core.spi.ContextAwareBase;
19 import ch.qos.logback.core.spi.PropertyContainer;
20 import ch.qos.logback.core.util.OptionHelper;
21
22 import static ch.qos.logback.core.CoreConstants.EMPTY_STRING;
23
24 /**
25 * <p>Abstract base class provides some scaffolding. It is intended to ease migration
26 * from <b>legacy</b> conditional processing in configuration files
27 * (e.g. <if>, <then>, <else>) using the Janino library. Nevertheless,
28 * it should also be useful in newly written code.</p>
29 *
30 * <p>Properties are looked up in the following order:</p>
31 *
32 * <ol>
33 * <li>In the local property container, usually the {@link ModelInterpretationContext} </li>
34 * <li>in the logger context</li>
35 * <li>system properties</li>
36 * <li>environment variables</li>
37 * </ol>
38 *
39 * @author Ceki Gülcü
40 * @see OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)
41 * @since 1.5.20
42 */
43 abstract public class PropertyConditionBase extends ContextAwareBase implements PropertyCondition {
44
45 /**
46 * Indicates whether this evaluator has been started.
47 */
48 boolean started;
49 /**
50 * <p>The local property container used for property lookups.</p>
51 *
52 * <p>Local properties correspond to the properties in the embedding
53 * configurator, i.e. usually the {@link ModelInterpretationContext} instance.</p>
54 */
55 PropertyContainer localPropertyContainer;
56
57 /**
58 * Returns the local property container used by this evaluator.
59 *
60 * <p>Local properties correspond to the properties in the embedding
61 * configurator, i.e. usually the {@link ModelInterpretationContext} instance.</p>
62 *
63 * @return the local property container
64 */
65 @Override
66 public PropertyContainer getLocalPropertyContainer() {
67 return localPropertyContainer;
68 }
69
70 /**
71 * Sets the local property container for this evaluator.
72 *
73 * <p>Local properties correspond to the properties in the embedding
74 * configurator, i.e. usually the {@link ModelInterpretationContext} instance.</p>
75 *
76 * @param aLocalPropertyContainer the local property container to set
77 */
78 @Override
79 public void setLocalPropertyContainer(PropertyContainer aLocalPropertyContainer) {
80 this.localPropertyContainer = aLocalPropertyContainer;
81 }
82
83 /**
84 * Checks if the property with the given key is null.
85 *
86 * <p>The property is looked up via the
87 * {@link OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)} method.
88 * See above for the lookup order.</p>
89 *
90 * @param k the property key
91 * @return true if the property is null, false otherwise
92 */
93 public boolean isNull(String k) {
94 String val = OptionHelper.propertyLookup(k, localPropertyContainer, getContext());
95 return (val == null);
96 }
97
98 /**
99 * Checks if the property with the given key is defined (not null).
100 *
101 * <p>The property is looked up via the
102 * {@link OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)} method.
103 * See above for the lookup order.</p>
104 *
105 * @param k the property key
106 * @return true if the property is defined, false otherwise
107 */
108 public boolean isDefined(String k) {
109 String val = OptionHelper.propertyLookup(k, localPropertyContainer, getContext());
110 return (val != null);
111 }
112
113 /**
114 * Retrieves the property value for the given key, returning an empty string if null.
115 * This is a shorthand for {@link #property(String)}.
116 *
117 * @param k the property key
118 * @return the property value or an empty string
119 */
120 public String p(String k) {
121 return property(k);
122 }
123
124 /**
125 * Retrieves the property value for the given key, returning an empty string if null.
126 *
127 * <p>The property is looked up via the
128 * {@link OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)} method.
129 * See above for the lookup order.</p>
130 *
131 * @param k the property key
132 * @return the property value or an empty string
133 */
134 public String property(String k) {
135 String val = OptionHelper.propertyLookup(k, localPropertyContainer, getContext());
136 if (val != null)
137 return val;
138 else
139 return EMPTY_STRING;
140 }
141
142 /**
143 * Compare the resolved property value with the provided expected value.
144 *
145 * <p>The property is looked up via the
146 * {@link OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)} method.
147 * See above for the lookup order.</p>
148 *
149 * <p>Returns {@code true} if the resolved property value is equal to {@code val}
150 * according to {@link String#equals(Object)}. If the resolved property value or {@code val} is null,
151 * then false is returned.</p>
152 *
153 * @param propertyKey the property key to look up
154 * @param value expected string value to compare against; must be non-null
155 * @return {@code true} if the resolved property equals {@code value},
156 * {@code false} otherwise or if either the resolved property or {@code value} is null.
157 * @since 1.5.24
158 */
159 public boolean propertyEquals(String propertyKey, String value) {
160 String actual = OptionHelper.propertyLookup(propertyKey, localPropertyContainer, getContext());
161 if (actual == null || value == null) {
162 return false;
163 }
164 return actual.equals(value);
165 }
166
167
168 /**
169 * Determine whether the resolved property value contains the given substring.
170 * <p>
171 *
172 * <p>The property is looked up via the
173 * {@link OptionHelper#propertyLookup(String, PropertyContainer, PropertyContainer)} method.
174 * See above for the lookup order.</p>
175 *
176 * <p>This method returns {@code true} if the resolved property value's
177 * {@link String#contains(CharSequence)} returns {@code true} for the supplied
178 * {@code inclusion}. False is returned if either the resolved property value or
179 * {@code inclusion} parameter is null.</p>
180 *
181 * @param k the property key to look up
182 * @param inclusion substring to search for in the resolved property value; must be non-null
183 * @return {@code true} if the property value contains {@code inclusion}, false otherwise or
184 * if either the resolved property value or {@code inclusion} is null
185 *
186 * @since 1.5.24
187 */
188 public boolean propertyContains(String k, String inclusion) {
189 String actual = OptionHelper.propertyLookup(k, localPropertyContainer, getContext());
190 if (actual == null || inclusion == null)
191 return false;
192
193 return actual.contains(inclusion);
194 }
195
196 /**
197 * Checks if this evaluator has been started.
198 *
199 * @return true if started, false otherwise
200 */
201 public boolean isStarted() {
202 return started;
203 }
204
205 /**
206 * Starts this evaluator.
207 */
208 public void start() {
209 started = true;
210 }
211
212 /**
213 * Stops this evaluator.
214 */
215 public void stop() {
216 started = false;
217 }
218 }