1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
package bjc.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.regex.Pattern;
import bjc.utils.funcutils.LambdaLock;
import bjc.utils.ioutils.SimpleProperties;
/**
* Database for storage of properties from external files.
*
* @author EVE
*
*/
public class PropertyDB {
private static SimpleProperties regexes;
private static Map<String, Pattern> compiledRegexes;
private static SimpleProperties formats;
/*
* Whether or not to log during the loading.
*/
private static final boolean LOGLOAD = false;
/*
* The lock to use to ensure a read can't happen during a reload
*/
private static LambdaLock loadLock = new LambdaLock();
static {
reloadProperties();
}
/**
* Reload all the properties from their files.
*
* NOTE: Any attempts to read from the property DB while properties are
* being loaded will block, to prevent reads from partial states.
*/
public static void reloadProperties() {
/*
* Do the load with the write lock taken.
*/
loadLock.write(() -> {
if (LOGLOAD) {
System.out.println("Reading regex properties:");
}
/*
* Load regexes.
*/
regexes = new SimpleProperties();
regexes.loadFrom(PropertyDB.class.getResourceAsStream("/regexes.sprop"), false);
if (LOGLOAD) {
regexes.outputProperties();
System.out.println();
}
compiledRegexes = new HashMap<>();
if (LOGLOAD) {
System.out.println("Reading format properties:");
}
/*
* Load formats.
*/
formats = new SimpleProperties();
formats.loadFrom(PropertyDB.class.getResourceAsStream("/formats.sprop"), false);
if (LOGLOAD) {
formats.outputProperties();
System.out.println();
}
});
}
/**
* Retrieve a persisted regular expression.
*
* @param key
* The name of the regular expression.
*
* @return The regular expression with that name.
*/
public static String getRegex(final String key) {
return loadLock.read(() -> {
if (!regexes.containsKey(key)) {
final String msg = String.format("No regular expression named '%s' found", key);
throw new NoSuchElementException(msg);
}
return regexes.get(key);
});
}
/**
* Retrieve a persisted regular expression, compiled into a regular
* expression.
*
* @param key
* The name of the regular expression.
*
* @return The regular expression with that name.
*/
public static Pattern getCompiledRegex(final String key) {
return loadLock.read(() -> {
if (!regexes.containsKey(key)) {
final String msg = String.format("No regular expression named '%s' found", key);
throw new NoSuchElementException(msg);
}
/*
* Get the regex, and cache a compiled version.
*/
return compiledRegexes.computeIfAbsent(key, strang -> {
return Pattern.compile(regexes.get(strang));
});
});
}
/**
* Retrieve a persisted format string.
*
* @param key
* The name of the format string.
*
* @return The format string with that name.
*/
public static String getFormat(final String key) {
return loadLock.read(() -> {
if (!formats.containsKey(key)) {
final String msg = String.format("No format string named '%s' found", key);
throw new NoSuchElementException(msg);
}
return formats.get(key);
});
}
/**
* Retrieve a persisted format string, and apply it to a set of
* arguments.
*
* @param key
* The name of the format string.
*
* @param objects
* The parameters to the format string.
*
* @return The format string with that name.
*/
public static String applyFormat(final String key, final Object... objects) {
return String.format(getFormat(key), objects);
}
}
|