ConfigurationValueBuilderHelper.java

1
package fr.sii.ogham.core.builder.configuration;
2
3
import static fr.sii.ogham.core.util.BuilderUtils.isExpression;
4
import static java.util.Optional.empty;
5
6
import java.util.ArrayList;
7
import java.util.List;
8
import java.util.Optional;
9
10
import fr.sii.ogham.core.builder.configurer.Configurer;
11
import fr.sii.ogham.core.builder.context.BuildContext;
12
import fr.sii.ogham.core.fluent.AbstractParent;
13
14
/**
15
 * Helper that allow registration of properties and default value but also
16
 * registers the value set by the developer.
17
 * 
18
 * <p>
19
 * If a value is explicitly set by developer, it means that the value is
20
 * hard-coded in its own code. This value can't be overridden by a property or
21
 * default value so the developer value always takes precedence.
22
 * 
23
 * For example, Ogham could be configured like this:
24
 * 
25
 * <pre>
26
 * .port()
27
 *   .properties("mail.smtp.port", "mail.port")
28
 *   .devaultValue(25)
29
 * </pre>
30
 * 
31
 * The developer can configure Ogham using a configuration file in the classpath
32
 * to provide values for local development environment. Example of content of
33
 * the configuration file:
34
 * 
35
 * <pre>
36
 * mail.smtp.port = 557
37
 * </pre>
38
 * 
39
 * The developer may want to test its code and may need to have a different port
40
 * value in test:
41
 * 
42
 * <pre>
43
 * &#64;Test
44
 * public void testMail() {
45
 *   MessagingBuilder builder = MessagingBuilder.standard();
46
 *   builder
47
 *     .email().sender(JavaMailBuilder.class)
48
 *       .port(10025)
49
 *   ...
50
 * </pre>
51
 * 
52
 * The value {@code 10025} must be the value available in the test regardless of
53
 * the value of the properties and default value.
54
 * 
55
 * <p>
56
 * <strong>NOTE:</strong> This class is for internal use (or extensions for
57
 * Ogham). The developer that uses Ogham should not see
58
 * {@link #setValue(Object)} and {@link #getValue()} methods.
59
 * 
60
 * 
61
 * @author Aurélien Baudet
62
 *
63
 * @param <P>
64
 *            the type of the parent
65
 * @param <V>
66
 *            the type of the value
67
 */
68
public class ConfigurationValueBuilderHelper<P, V> extends AbstractParent<P> implements ConfigurationValueBuilder<P, V> {
69
	private final Class<V> valueClass;
70
	private final BuildContext buildContext;
71
	private final List<String> properties;
72
	private V defaultValue;
73
	private V value;
74
	private Optional<V> optionalValue;
75
76
	/**
77
	 * Initializes with the parent builder and the type of the value used for
78
	 * conversion.
79
	 * 
80
	 * @param parent
81
	 *            the parent builder
82
	 * @param valueClass
83
	 *            the type of the value
84
	 * @param buildContext
85
	 *            for registering instances and property evaluation
86
	 */
87
	public ConfigurationValueBuilderHelper(P parent, Class<V> valueClass, BuildContext buildContext) {
88
		super(parent);
89
		this.valueClass = valueClass;
90
		this.buildContext = buildContext;
91
		properties = new ArrayList<>();
92
		optionalValue = empty();
93
	}
94
95
	@Override
96
	public ConfigurationValueBuilderHelper<P, V> properties(String... properties) {
97
		for (String property : properties) {
98 1 1. properties : negated conditional → RUN_ERROR
			if (!isExpression(property)) {
99
				property = "${" + property + "}";
100
			}
101
			this.properties.add(property);
102
		}
103 1 1. properties : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::properties → RUN_ERROR
		return this;
104
	}
105
106
	@Override
107
	public ConfigurationValueBuilderHelper<P, V> defaultValue(V value) {
108
		defaultValue = value;
109 1 1. defaultValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::defaultValue → RUN_ERROR
		return this;
110
	}
111
112
	@Override
113
	public ConfigurationValueBuilderHelper<P, V> defaultValue(MayOverride<V> possibleNewValue) {
114
		defaultValue = possibleNewValue.override(defaultValue);
115 1 1. defaultValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::defaultValue → RUN_ERROR
		return this;
116
	}
117
118
	@Override
119
	@SuppressWarnings("squid:S3553")
120
	public ConfigurationValueBuilderHelper<P, V> value(Optional<V> optionalValue) {
121 1 1. value : negated conditional → NO_COVERAGE
		if (optionalValue.isPresent()) {
122
			this.optionalValue = optionalValue;
123
		}
124 1 1. value : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::value → NO_COVERAGE
		return this;
125
	}
126
127
	/**
128
	 * If a value is explicitly set by developer, it means that the value is
129
	 * hard-coded in its own code. This value can't be overridden by a property
130
	 * or default value so the developer value always takes precedence.
131
	 * 
132
	 * For example, Ogham could be configured like this:
133
	 * 
134
	 * <pre>
135
	 * .port()
136
	 *   .properties("mail.smtp.port", "mail.port")
137
	 *   .devaultValue(25)
138
	 * </pre>
139
	 * 
140
	 * The developer can configure Ogham using a configuration file in the
141
	 * classpath to provide values for local development environment. Example of
142
	 * content of the configuration file:
143
	 * 
144
	 * <pre>
145
	 * mail.smtp.port = 557
146
	 * </pre>
147
	 * 
148
	 * The developer may want to test its code and may need to have a different
149
	 * port value in test:
150
	 * 
151
	 * <pre>
152
	 * &#64;Test
153
	 * public void testMail() {
154
	 *   MessagingBuilder builder = MessagingBuilder.standard();
155
	 *   builder
156
	 *     .email().sender(JavaMailBuilder.class)
157
	 *       .port(10025)
158
	 *   ...
159
	 * </pre>
160
	 * 
161
	 * The value {@code 10025} must be the value available in the test
162
	 * regardless of the value of the properties and default value.
163
	 * 
164
	 * <p>
165
	 * <strong>IMPORTANT:</strong> {@link Configurer}s <strong>should
166
	 * not</strong> use this method directly because it prevents the possibility
167
	 * to override the value from external configuration.
168
	 * 
169
	 * @param value
170
	 *            the value set by the developer in its own code
171
	 */
172
	public void setValue(V value) {
173
		this.value = value;
174
	}
175
176
	/**
177
	 * Get the final value. The first non-null value is returned:
178
	 * 
179
	 * <ol>
180
	 * <li>If the a non-null value has been set using {@link #setValue(Object)},
181
	 * this value is returned</li>
182
	 * <li>If an optional value has been set using {@link #value(Optional)}, and
183
	 * {@link Optional#isPresent()} returns true this value is returned</li>
184
	 * <li>If property keys have been registered and one has been evaluated to a
185
	 * non-null value, this value is returned</li>
186
	 * <li>If a default value has been registered, the default value is
187
	 * returned</li>
188
	 * <li>null is returned</li>
189
	 * </ol>
190
	 * 
191
	 * @return the value
192
	 */
193
	public V getValue() {
194 1 1. getValue : negated conditional → RUN_ERROR
		if (value != null) {
195 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR
			return value;
196
		}
197 1 1. getValue : negated conditional → RUN_ERROR
		if (optionalValue.isPresent()) {
198 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → NO_COVERAGE
			return optionalValue.get();
199
		}
200
		V prop = buildContext.evaluate(properties, valueClass);
201 1 1. getValue : negated conditional → RUN_ERROR
		if (prop != null) {
202 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR
			return prop;
203
		}
204 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR
		return defaultValue;
205
	}
206
207
	/**
208
	 * Get the final value. The first non-null value is returned:
209
	 * 
210
	 * <ol>
211
	 * <li>If the a non-null value has been set using {@link #setValue(Object)},
212
	 * this value is returned</li>
213
	 * <li>If an optional value has been set using {@link #value(Optional)}, and
214
	 * {@link Optional#isPresent()} returns true this value is returned</li>
215
	 * <li>If property keys have been registered and one has been evaluated to a
216
	 * non-null value, this value is returned</li>
217
	 * <li>If a default value has been registered, the default value is
218
	 * returned</li>
219
	 * <li>The default value provided as parameter is used</li>
220
	 * </ol>
221
	 * 
222
	 * @param defaultValue
223
	 *            the default value to use if there isn't a non-null value
224
	 * @return the value
225
	 */
226
	public V getValue(V defaultValue) {
227
		V configuredValue = getValue();
228 1 1. getValue : negated conditional → RUN_ERROR
		if (configuredValue != null) {
229 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR
			return configuredValue;
230
		}
231 1 1. getValue : replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR
		return defaultValue;
232
	}
233
234
	/**
235
	 * Returns true if a value, default value or properties have been set.
236
	 * 
237
	 * @return true if there is a value, default value or at least one property
238
	 */
239
	public boolean hasValueOrProperties() {
240 4 1. hasValueOrProperties : negated conditional → NO_COVERAGE
2. hasValueOrProperties : negated conditional → NO_COVERAGE
3. hasValueOrProperties : negated conditional → NO_COVERAGE
4. hasValueOrProperties : replaced boolean return with true for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::hasValueOrProperties → NO_COVERAGE
		return value != null || !properties.isEmpty() || defaultValue != null;
241
	}
242
243
}

Mutations

98

1.1
Location : properties
Killed by :
negated conditional → RUN_ERROR

103

1.1
Location : properties
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::properties → RUN_ERROR

109

1.1
Location : defaultValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::defaultValue → RUN_ERROR

115

1.1
Location : defaultValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::defaultValue → RUN_ERROR

121

1.1
Location : value
Killed by :
negated conditional → NO_COVERAGE

124

1.1
Location : value
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::value → NO_COVERAGE

194

1.1
Location : getValue
Killed by :
negated conditional → RUN_ERROR

195

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR

197

1.1
Location : getValue
Killed by :
negated conditional → RUN_ERROR

198

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → NO_COVERAGE

201

1.1
Location : getValue
Killed by :
negated conditional → RUN_ERROR

202

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR

204

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR

228

1.1
Location : getValue
Killed by :
negated conditional → RUN_ERROR

229

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR

231

1.1
Location : getValue
Killed by :
replaced return value with null for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::getValue → RUN_ERROR

240

1.1
Location : hasValueOrProperties
Killed by :
negated conditional → NO_COVERAGE

2.2
Location : hasValueOrProperties
Killed by :
negated conditional → NO_COVERAGE

3.3
Location : hasValueOrProperties
Killed by :
negated conditional → NO_COVERAGE

4.4
Location : hasValueOrProperties
Killed by :
replaced boolean return with true for fr/sii/ogham/core/builder/configuration/ConfigurationValueBuilderHelper::hasValueOrProperties → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.13.1