-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathConfigSource.java
More file actions
215 lines (203 loc) · 9.05 KB
/
ConfigSource.java
File metadata and controls
215 lines (203 loc) · 9.05 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
******************************************************************************
* Copyright (c) 2009-2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* 2009 - Mark Struberg
* Ordinal solution in Apache OpenWebBeans
* 2011-12-28 - Mark Struberg & Gerhard Petracek
* Contributed to Apache DeltaSpike fb0131106481f0b9a8fd
* 2016-07-14 - Mark Struberg
* Extracted the Config part out of DeltaSpike and proposed as Microprofile-Config cf41cf130bcaf5447ff8
* 2016-11-14 - Emily Jiang / IBM Corp
* Methods renamed, JavaDoc and cleanup
*
*******************************************************************************/
package jakarta.config.spi;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
/**
* <p>Implement this interfaces to provide a ConfigSource.
* A ConfigSource provides configuration values from a specific place, like JNDI configuration, a properties file, etc.
* A ConfigSource is always read-only, any potential updates of the configured values must be handled directly inside each ConfigSource.
*
* <p>
* The default config sources always available by default are:
* <ol>
* <li>System properties (ordinal=400)</li>
* <li>Environment properties (ordinal=300)
* <p>Some operating systems allow only alphabetic characters or an underscore(_), in environment variables.
* Other characters such as ., /, etc may be disallowed.
* In order to set a value for a config property that has a name containing such disallowed characters from an environment variable,
* the following rules are used.
* This ConfigSource searches for potentially 3 environment variables with a given property name (e.g. {@code "com.ACME.size"}):</p>
* <ol>
* <li>Exact match (i.e. {@code "com.ACME.size"})</li>
* <li>Replace the character that is neither alphanumeric nor '_' with '_' (i.e. {@code "com_ACME_size"})</li>
* <li>Replace the character that is neither alphanumeric nor '_' with '_' and convert to upper case
* (i.e. {@code "COM_ACME_SIZE"})</li>
* </ol>
* <p>The first environment variable that is found is returned by this ConfigSource.</p>
* </li>
* <li>/META-INF/javaconfig.properties (ordinal=100)</li>
* </ol>
*
* <p>Custom ConfigSource will get picked up via the {@link java.util.ServiceLoader} mechanism and and can be registered by
* providing a file
* <pre>
* META-INF/services/ConfigSource
* </pre>
* which contains the fully qualified {@code ConfigSource} implementation class name as content.
*
* <p>Adding a dynamic amount of custom config sources can be done programmatically via
* {@link ConfigSourceProvider}.
*
* <p>If a ConfigSource implements the {@link AutoCloseable} interface
* then the {@link AutoCloseable#close()} method will be called when
* the underlying {@link jakarta.config.Config} is being released.
*
* <p> If you register the same {@code ConfigSource} instance within multiple {@link jakarta.config.Config} then non-portable behaviour results.
*
* @author <a href="mailto:struberg@apache.org">Mark Struberg</a>
* @author <a href="mailto:gpetracek@apache.org">Gerhard Petracek</a>
* @author <a href="mailto:emijiang@uk.ibm.com">Emily Jiang</a>
* @author <a href="mailto:john.d.ament@gmail.com">John D. Ament</a>
* @author <a href="mailto:tomas.langer@oracle.com">Tomas Langer</a>
*
*/
public interface ConfigSource {
String CONFIG_ORDINAL = "config_ordinal";
int DEFAULT_ORDINAL = 100;
/**
* Return the properties in this config source.
*
* @return the map containing the properties in this config source if these can be scanned, or empty Map
* @see #isScannable()
*/
Map<String, String> getProperties();
/**
* Gets all property names known to this config source, without evaluating the values.
*
* For backwards compatibility, there is a default implementation that just returns the keys of {@code getProperties()}
* slower ConfigSource implementations should replace this with a more performant implementation
*
* @return the set of property keys that are known to this config source if these can be scanned or empty Set
* @see #isScannable()
*/
default Set<String> getPropertyNames() {
return getProperties().keySet();
}
/**
* Return the ordinal for this config source. If a property is specified in multiple config sources, the value
* in the config source with the highest ordinal takes precedence.
* For the config sources with the same ordinal value, the config source names will
* be used for sorting according to string sorting criteria.
* Note that this property only gets evaluated during ConfigSource discovery.
*
* The default ordinals for the default config sources:
* <ol>
* <li>System properties (default ordinal=400)</li>
* <li>Environment properties (default ordinal=300)</li>
* <li>/META-INF/javaconfig.properties (default ordinal=100)</li>
* </ol>
*
*
* Any ConfigSource part of an application will typically use an ordinal between 0 and 200.
* ConfigSource provided by the container or 'environment' typically use an ordinal higher than 200.
* A framework which intends have values overwritten by the application will use ordinals between 0 and 100.
* The property "config_ordinal" can be specified to override the default value.
*
* @return the ordinal value
*/
default int getOrdinal() {
String configOrdinal = getValue(CONFIG_ORDINAL);
if (configOrdinal != null) {
try {
return Integer.parseInt(configOrdinal);
}
catch (NumberFormatException ignored) {
}
}
return DEFAULT_ORDINAL;
}
/**
* Return the value for the specified property in this config source.
*
* @param propertyName the property name
* @return the property value, or {@code null} when property is not defined by this config source
*/
String getValue(String propertyName);
/**
* The name of this config source might be used for logging or analysis of configured values.
*
* @return the 'name' of the configuration source, e.g. 'property-file mylocation/myproperty.properties'
*/
String getName();
/**
* Determines if this config source should be scanned for its list of properties.
*
* Generally, slow ConfigSources should return false here.
*
* @return {@code true} if this ConfigSource should be scanned for its list of properties,
* {@code false} if it should not be scanned.
*/
default boolean isScannable() {
return true;
}
/**
* The callback should get invoked if an attribute change got detected inside the ConfigSource.
*
* @param callback will be set by the {@link jakarta.config.Config} after this
* {@code ConfigSource} got created and before any configured values
* get served.
* @return ChangeSupport informing the {@link jakarta.config.Config} implementation about support for changes by this source
* @see ChangeSupport
*/
default ChangeSupport setAttributeChangeCallback(Consumer<Set<String>> callback) {
// do nothing by default. Just for compat with older ConfigSources.
// return unsupported to tell config that it must re-query this source every time
return ChangeSupport.UNSUPPORTED;
}
/**
* What kind of change support this config source has.
* <p>
* {@link jakarta.config.Config} implementations may use this information for internal optimizations.
*/
enum ChangeSupport {
/**
* Config change is supported, this config source will invoke the callback provided by
* {@link ConfigSource#setAttributeChangeCallback(Consumer)}.
* <p>
* Example: File based config source that watches the file for changes
*/
SUPPORTED,
/**
* Config change is not supported. Configuration values can change, though this change is not reported back.
* <p>
* Example: LDAP based config source
*/
UNSUPPORTED,
/**
* Configuration values cannot change for the lifetime of this {@link ConfigSource}.
* <p>
* Example: Environment variables config source, classpath resource config source
*/
IMMUTABLE
}
}