Skip to content

Commit 131c5ba

Browse files
committed
Fixing the MonetaryConfig issue
1 parent d79797f commit 131c5ba

File tree

4 files changed

+74
-34
lines changed

4 files changed

+74
-34
lines changed

moneta-core/src/main/java/org/javamoney/moneta/DefaultMonetaryContextFactory.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
* {@link RoundingMode}.
4848
*/
4949
class DefaultMonetaryContextFactory {
50-
// TODO this should probably go to "convert" in future releases. Analyze feasability of refactoring.
5150
public MonetaryContext getContext() {
5251
try {
5352
Map<String, String> config = MonetaryConfig.getConfig();

moneta-core/src/main/java/org/javamoney/moneta/spi/DefaultConfigProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2020, Anatole Tresch, Werner Keil and others by the @author tag.
2+
* Copyright (c) 2012, 2020, Werner Keil and others by the @author tag.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
55
* use this file except in compliance with the License. You may obtain a copy of
@@ -26,6 +26,8 @@
2626
* Default implementation of the JavaMoney configuration provider reading all present properties from
2727
* {@code classpath*:javamoney.properties}. Any key can be explicitly overridden by using system
2828
* properties.
29+
* @deprecated Preview, for 2.0 we may reconsider that e.g. backed by a full scale config subsystem like
30+
* Spring or MP Config but for now this is error-prone, see https://hibernate.atlassian.net/browse/HV-1793
2931
*/
3032
public class DefaultConfigProvider implements MonetaryConfigProvider {
3133

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2012, 2020, Anatole Tresch, Werner Keil and others by the @author tag.
2+
Copyright (c) 2012, 2020, Werner Keil and others by the @author tag.
33
44
Licensed under the Apache License, Version 2.0 (the "License"); you may not
55
use this file except in compliance with the License. You may obtain a copy of
@@ -15,96 +15,133 @@
1515
*/
1616
package org.javamoney.moneta.spi;
1717

18-
import javax.money.spi.Bootstrap;
18+
import java.io.IOException;
19+
import java.net.URL;
1920
import java.util.*;
21+
import java.util.logging.Level;
2022
import java.util.logging.Logger;
2123

2224
/**
2325
* Loader for the Java Money JSR configuration.
2426
*
2527
* @author Anatole Tresch
26-
* @deprecated Will be removed from the SPI. Implement and register an instance of {@link MonetaryConfigProvider}
27-
* instead of.
28-
* @see MonetaryConfigProvider
28+
* @author Werner Keil
2929
*/
30-
@Deprecated
3130
public final class MonetaryConfig {
3231

3332
private static final Logger LOG = Logger
3433
.getLogger(MonetaryConfig.class.getName());
3534

3635
private static final MonetaryConfig INSTANCE = new MonetaryConfig();
3736

37+
private final Map<String, String> config = new HashMap<>();
38+
private final Map<String, Integer> priorities = new HashMap<>();
39+
3840
private MonetaryConfig() {
41+
try {
42+
Enumeration<URL> urls = getClass().getClassLoader().getResources(
43+
"javamoney.properties");
44+
while (urls.hasMoreElements()) {
45+
URL url = urls.nextElement();
46+
try {
47+
Properties props = new Properties();
48+
props.load(url.openStream());
49+
updateConfig(props);
50+
} catch (Exception e) {
51+
LOG.log(Level.SEVERE,
52+
"Error loading javamoney.properties, ignoring "
53+
+ url, e);
54+
}
55+
}
56+
} catch (IOException e) {
57+
LOG.log(Level.SEVERE, "Error loading javamoney.properties.", e);
58+
}
3959
}
4060

41-
/**
42-
* Sets a new config value. Note that when a custom {@link MonetaryConfigProvider} is registered, writing
43-
* of configuration values is not supported. In this case a debug log (fine) is written.
44-
*
45-
* @param key the key to be set, not null.
46-
* @param value the new value, or null.
47-
* @return the previous value.
48-
*/
49-
public static String setValue(String key, String value){
50-
if(Bootstrap.getService(MonetaryConfigProvider.class) instanceof DefaultConfigProvider) {
51-
DefaultConfigProvider defaultConfigProvider = (DefaultConfigProvider)Bootstrap.getService(MonetaryConfigProvider.class);
52-
if (value == null) {
53-
return defaultConfigProvider.config.remove(key);
61+
private void updateConfig(Properties props) {
62+
for (Map.Entry<Object, Object> en : props.entrySet()) {
63+
String key = en.getKey().toString();
64+
String value = en.getValue().toString();
65+
int prio = 0;
66+
if (key.startsWith("{")) {
67+
int index = key.indexOf('}');
68+
if (index > 0) {
69+
String prioString = key.substring(1, index);
70+
try {
71+
prio = Integer.parseInt(prioString);
72+
key = key.substring(index + 1);
73+
} catch (NumberFormatException e) {
74+
LOG.warning("Invalid config key in javamoney.properties: " + key);
75+
}
76+
}
77+
}
78+
Integer existingPrio = priorities.get(key);
79+
if (Objects.isNull(existingPrio)) {
80+
priorities.put(key, prio);
81+
config.put(key, value);
82+
} else if (existingPrio < prio) {
83+
priorities.put(key, prio);
84+
config.put(key, value);
85+
} else if (existingPrio == prio) {
86+
throw new IllegalStateException(
87+
"AmbiguousConfiguration detected for '" + key + "'.");
5488
}
55-
return defaultConfigProvider.config.put(key, value);
89+
// else ignore entry with lower prio!
5690
}
57-
LOG.fine("MonetaryConfig does not support deprecated write of " + key + "=" + value);
58-
return null;
91+
}
92+
93+
public static String setValue(String key, String value){
94+
if(value==null){
95+
return INSTANCE.config.remove(key);
96+
}
97+
return INSTANCE.config.put(key, value);
5998
}
6099

61100
public static Optional<String> getString(String key){
62-
return Optional.ofNullable(Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key));
101+
return Optional.ofNullable(INSTANCE.config.get(key));
63102
}
64103

65104
public static Optional<Boolean> getBoolean(String key){
66-
String val = Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key);
105+
String val = INSTANCE.config.get(key);
67106
if(val != null){
68107
return Optional.ofNullable(Boolean.parseBoolean(val));
69108
}
70109
return Optional.empty();
71110
}
72111

73112
public static Optional<Integer> getInteger(String key){
74-
String val = Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key);
113+
String val = INSTANCE.config.get(key);
75114
if(val != null){
76115
return Optional.ofNullable(Integer.parseInt(val));
77116
}
78117
return Optional.empty();
79118
}
80119

81120
public static Optional<Long> getLong(String key){
82-
String val = Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key);
121+
String val = INSTANCE.config.get(key);
83122
if(val != null){
84123
return Optional.ofNullable(Long.parseLong(val));
85124
}
86125
return Optional.empty();
87126
}
88127

89128
public static Optional<Float> getFloat(String key){
90-
String val = Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key);
129+
String val = INSTANCE.config.get(key);
91130
if(val != null){
92131
return Optional.ofNullable(Float.parseFloat(val));
93132
}
94133
return Optional.empty();
95134
}
96135

97136
public static Optional<Double> getDouble(String key){
98-
String val = Bootstrap.getService(MonetaryConfigProvider.class).getProperty(key);
137+
String val = INSTANCE.config.get(key);
99138
if(val != null){
100139
return Optional.ofNullable(Double.parseDouble(val));
101140
}
102141
return Optional.empty();
103142
}
104143

105144
public static Map<String, String> getConfig() {
106-
return Collections.unmodifiableMap(Bootstrap.getService(MonetaryConfigProvider.class).getProperties());
145+
return Collections.unmodifiableMap(INSTANCE.config);
107146
}
108-
109-
110147
}

moneta-core/src/main/java/org/javamoney/moneta/spi/MonetaryConfigProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
/**
2121
* Dynamic interface for providing monetary configuration. Register a custom implementation with the {@link java.util.ServiceLoader}
2222
* to configure JavaMoney.
23+
* @deprecated Preview, for 2.0 we may reconsider that e.g. backed by a full scale config subsystem like
24+
* Spring or MP Config but for now this is error-prone, see https://hibernate.atlassian.net/browse/HV-1793
2325
*/
2426
public interface MonetaryConfigProvider {
2527

2628
/**
27-
* Simple methoid to get a property.
29+
* Simple method to get a property.
2830
* @param key the key, not null.
2931
* @return the value, or null.
3032
*/

0 commit comments

Comments
 (0)