Skip to content

Commit 22b98b8

Browse files
authored
Support System Properties as a configuration source (#20)
* Support system properties as a configuration source Update README Support system properties as a configuration source * Rewrite PropertiesConfiguration to use a Map instead of Properties as class variable, refine tests * Rename variable in PropertiesConfiguration
1 parent f8e5498 commit 22b98b8

File tree

3 files changed

+281
-0
lines changed

3 files changed

+281
-0
lines changed

README.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CNF-01 is a library that provides immutable configuration for Java projects. Imm
1414
// List your project's features
1515
- Provides immutable configurations for:
1616
. configuration files / path properties (`PathConfiguration`)
17+
. System Properties (`PropertiesConfiguration`)
1718
. environment variables (`EnvironmentConfiguration`)
1819
- Default configurations in case the provided configurations from a source are not found or are otherwise broken (`DefaultConfiguration`)
1920

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Teragrep Configuration Library for Java (cnf_01)
3+
* Copyright (C) 2024 Suomen Kanuuna Oy
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
*
19+
* Additional permission under GNU Affero General Public License version 3
20+
* section 7
21+
*
22+
* If you modify this Program, or any covered work, by linking or combining it
23+
* with other code, such other code is not for that reason alone subject to any
24+
* of the requirements of the GNU Affero GPL version 3 as long as this Program
25+
* is the same Program as licensed from Suomen Kanuuna Oy without any additional
26+
* modifications.
27+
*
28+
* Supplemented terms under GNU Affero General Public License version 3
29+
* section 7
30+
*
31+
* Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
32+
* versions must be marked as "Modified version of" The Program.
33+
*
34+
* Names of the licensors and authors may not be used for publicity purposes.
35+
*
36+
* No rights are granted for use of trade names, trademarks, or service marks
37+
* which are in The Program if any.
38+
*
39+
* Licensee must indemnify licensors and authors for any liability that these
40+
* contractual assumptions impose on licensors and authors.
41+
*
42+
* To the extent this program is licensed as part of the Commercial versions of
43+
* Teragrep, the applicable Commercial License may apply to this file if you as
44+
* a licensee so wish it.
45+
*/
46+
package com.teragrep.cnf_01;
47+
48+
import org.slf4j.Logger;
49+
import org.slf4j.LoggerFactory;
50+
51+
import java.util.Collections;
52+
import java.util.Map;
53+
import java.util.Objects;
54+
import java.util.Properties;
55+
import java.util.stream.Collectors;
56+
57+
/**
58+
* Provides unmodifiable configuration for Java's Properties object. Uses System properties by default if the
59+
* constructor is not given a parameter.
60+
*/
61+
public final class PropertiesConfiguration implements Configuration {
62+
63+
private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesConfiguration.class);
64+
65+
private final Map<String, String> configuration;
66+
67+
public PropertiesConfiguration() {
68+
this(System.getProperties());
69+
}
70+
71+
public PropertiesConfiguration(final Properties properties) {
72+
this(
73+
Collections
74+
.unmodifiableMap(
75+
properties
76+
.entrySet()
77+
.stream()
78+
.collect(
79+
Collectors
80+
.toMap(
81+
entry -> entry.getKey().toString(),
82+
entry -> entry.getValue().toString()
83+
)
84+
)
85+
)
86+
);
87+
}
88+
89+
/**
90+
* Private constructor so that a map can't be given as parameter by users. It would break immutability.
91+
*
92+
* @param configuration the configuration as an immutable Map
93+
*/
94+
private PropertiesConfiguration(final Map<String, String> configuration) {
95+
this.configuration = configuration;
96+
}
97+
98+
@Override
99+
public Map<String, String> asMap() {
100+
LOGGER.debug("Returning configuration map generated from properties.");
101+
LOGGER.trace("Returning configuration map <[{}]>", configuration);
102+
103+
return configuration;
104+
}
105+
106+
@Override
107+
public boolean equals(final Object o) {
108+
if (this == o) {
109+
return true;
110+
}
111+
else if (o == null || getClass() != o.getClass()) {
112+
return false;
113+
}
114+
final PropertiesConfiguration config = (PropertiesConfiguration) o;
115+
return configuration.equals(config.configuration);
116+
}
117+
118+
@Override
119+
public int hashCode() {
120+
return Objects.hashCode(configuration);
121+
}
122+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Teragrep Configuration Library for Java (cnf_01)
3+
* Copyright (C) 2024 Suomen Kanuuna Oy
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
*
19+
* Additional permission under GNU Affero General Public License version 3
20+
* section 7
21+
*
22+
* If you modify this Program, or any covered work, by linking or combining it
23+
* with other code, such other code is not for that reason alone subject to any
24+
* of the requirements of the GNU Affero GPL version 3 as long as this Program
25+
* is the same Program as licensed from Suomen Kanuuna Oy without any additional
26+
* modifications.
27+
*
28+
* Supplemented terms under GNU Affero General Public License version 3
29+
* section 7
30+
*
31+
* Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
32+
* versions must be marked as "Modified version of" The Program.
33+
*
34+
* Names of the licensors and authors may not be used for publicity purposes.
35+
*
36+
* No rights are granted for use of trade names, trademarks, or service marks
37+
* which are in The Program if any.
38+
*
39+
* Licensee must indemnify licensors and authors for any liability that these
40+
* contractual assumptions impose on licensors and authors.
41+
*
42+
* To the extent this program is licensed as part of the Commercial versions of
43+
* Teragrep, the applicable Commercial License may apply to this file if you as
44+
* a licensee so wish it.
45+
*/
46+
package com.teragrep.cnf_01;
47+
48+
import nl.jqno.equalsverifier.EqualsVerifier;
49+
import org.junit.jupiter.api.Assertions;
50+
import org.junit.jupiter.api.Test;
51+
52+
import java.util.Map;
53+
import java.util.Properties;
54+
55+
public class PropertiesConfigurationTest {
56+
57+
@Test
58+
public void testSystemProperties() {
59+
System.setProperty("foo", "bar");
60+
System.setProperty("bar", "foo");
61+
62+
PropertiesConfiguration config = new PropertiesConfiguration(); // uses System.getProperties()
63+
// clearing properties doesn't affect PropertiesConfiguration
64+
System.clearProperty("foo");
65+
System.clearProperty("bar");
66+
67+
Map<String, String> result = config.asMap();
68+
69+
Assertions.assertEquals("bar", result.get("foo"));
70+
Assertions.assertEquals("foo", result.get("bar"));
71+
}
72+
73+
@Test
74+
public void testProperties() {
75+
Properties properties = new Properties();
76+
properties.put("foo", "bar");
77+
properties.put("bar", "foo");
78+
79+
PropertiesConfiguration config = new PropertiesConfiguration(properties);
80+
// modifying the original properties doesn't modify the result map
81+
properties.put("biz", "buz");
82+
83+
Map<String, String> result = config.asMap();
84+
85+
Assertions.assertEquals(2, result.size());
86+
Assertions.assertEquals("bar", result.get("foo"));
87+
Assertions.assertEquals("foo", result.get("bar"));
88+
}
89+
90+
@Test
91+
public void testEmptyProperties() {
92+
Properties properties = new Properties();
93+
94+
PropertiesConfiguration config = new PropertiesConfiguration(properties);
95+
Map<String, String> result = config.asMap();
96+
97+
Assertions.assertEquals(0, result.size());
98+
}
99+
100+
@Test
101+
public void testEqualsWithSystemProperties() {
102+
PropertiesConfiguration config1 = new PropertiesConfiguration();
103+
PropertiesConfiguration config2 = new PropertiesConfiguration();
104+
105+
config1.asMap();
106+
Assertions.assertEquals(config1, config2);
107+
}
108+
109+
@Test
110+
public void testEqualsWithProperties() {
111+
Properties properties1 = new Properties();
112+
properties1.put("foo", "bar");
113+
114+
Properties properties2 = new Properties();
115+
properties2.put("foo", "bar");
116+
117+
PropertiesConfiguration config1 = new PropertiesConfiguration(properties1);
118+
// modifying properties1 doesn't modify immutable PropertiesConfiguration
119+
properties1.put("bar", "foo");
120+
121+
PropertiesConfiguration config2 = new PropertiesConfiguration(properties2);
122+
123+
config1.asMap();
124+
Assertions.assertEquals(config1, config2);
125+
}
126+
127+
@Test
128+
public void testNotEquals() {
129+
Properties properties = new Properties();
130+
properties.put("foo", "bar");
131+
132+
PropertiesConfiguration config1 = new PropertiesConfiguration();
133+
PropertiesConfiguration config2 = new PropertiesConfiguration(properties);
134+
135+
Assertions.assertNotEquals(config1, config2);
136+
}
137+
138+
@Test
139+
public void testHashCode() {
140+
Properties properties1 = new Properties();
141+
properties1.put("foo", "bar");
142+
143+
Properties properties2 = new Properties();
144+
properties2.put("foo", "bar");
145+
146+
PropertiesConfiguration config1 = new PropertiesConfiguration(properties1);
147+
PropertiesConfiguration config2 = new PropertiesConfiguration(properties2);
148+
PropertiesConfiguration difConfig = new PropertiesConfiguration();
149+
150+
Assertions.assertEquals(config1.hashCode(), config2.hashCode());
151+
Assertions.assertNotEquals(config1.hashCode(), difConfig.hashCode());
152+
}
153+
154+
@Test
155+
public void testEqualsVerifier() {
156+
EqualsVerifier.forClass(PropertiesConfiguration.class).withNonnullFields("configuration").verify();
157+
}
158+
}

0 commit comments

Comments
 (0)