Skip to content

Commit ee20423

Browse files
committed
ConfigParseOptions, shared to all, FileUtils, JVM to JVM Native
1 parent ddc343a commit ee20423

File tree

6 files changed

+563
-0
lines changed

6 files changed

+563
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
/**
2+
* Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
3+
*/
4+
package org.ekrich.config
5+
6+
import org.ekrich.config.impl.ConfigImplUtil
7+
import org.ekrich.config.impl.PlatformThread
8+
9+
/**
10+
* A set of options related to parsing.
11+
*
12+
* <p> This object is immutable, so the "setters" return a new object.
13+
*
14+
* <p> Here is an example of creating a custom `ConfigParseOptions`:
15+
*
16+
* <pre> ConfigParseOptions options = ConfigParseOptions.defaults()
17+
* .setSyntax(ConfigSyntax.JSON) .setAllowMissing(false) </pre>
18+
*/
19+
object ConfigParseOptions {
20+
21+
/**
22+
* Gets an instance of `ConfigParseOptions` with all fields set to the default
23+
* values. Start with this instance and make any changes you need.
24+
*
25+
* @return
26+
* the default parse options
27+
*/
28+
def defaults = new ConfigParseOptions(null, null, true, null, null)
29+
}
30+
31+
final class ConfigParseOptions private (
32+
val syntax: ConfigSyntax,
33+
val originDescription: String,
34+
val allowMissing: Boolean,
35+
val includer: ConfigIncluder,
36+
val classLoader: ClassLoader
37+
) {
38+
39+
/**
40+
* Set the file format. If set to null, try to guess from any available
41+
* filename extension; if guessing fails, assume [[ConfigSyntax#CONF]].
42+
*
43+
* @param syntax
44+
* a syntax or `null` for best guess
45+
* @return
46+
* options with the syntax set
47+
*/
48+
def setSyntax(syntax: ConfigSyntax): ConfigParseOptions =
49+
if (this.syntax == syntax) this
50+
else
51+
new ConfigParseOptions(
52+
syntax,
53+
this.originDescription,
54+
this.allowMissing,
55+
this.includer,
56+
this.classLoader
57+
)
58+
59+
/**
60+
* Set the file format. If set to null, assume [[ConfigSyntax#CONF]].
61+
*
62+
* @param filename
63+
* a configuration file name
64+
* @return
65+
* options with the syntax set
66+
*/
67+
def setSyntaxFromFilename(filename: String): ConfigParseOptions = {
68+
val syntax = ConfigImplUtil.syntaxFromExtension(filename)
69+
setSyntax(syntax)
70+
}
71+
72+
/**
73+
* Gets the current syntax option, which may be null for "any".
74+
*
75+
* @return
76+
* the current syntax or null
77+
*/
78+
def getSyntax: ConfigSyntax = syntax
79+
80+
/**
81+
* Set a description for the thing being parsed. In most cases this will be
82+
* set up for you to something like the filename, but if you provide just an
83+
* input stream you might want to improve on it. Set to null to allow the
84+
* library to come up with something automatically. This description is the
85+
* basis for the [[ConfigOrigin]] of the parsed values.
86+
*
87+
* @param originDescription
88+
* description to put in the [[ConfigOrigin]]
89+
* @return
90+
* options with the origin description set
91+
*/
92+
def setOriginDescription(originDescription: String): ConfigParseOptions = { // findbugs complains about == here but is wrong, do not "fix"
93+
if (this.originDescription == originDescription)
94+
this
95+
else if (this.originDescription != null && originDescription != null && this.originDescription == originDescription)
96+
this
97+
else
98+
new ConfigParseOptions(
99+
this.syntax,
100+
originDescription,
101+
this.allowMissing,
102+
this.includer,
103+
this.classLoader
104+
)
105+
}
106+
107+
/**
108+
* Gets the current origin description, which may be null for "automatic".
109+
*
110+
* @return
111+
* the current origin description or null
112+
*/
113+
def getOriginDescription: String = originDescription
114+
115+
/** this is package-private, not public API */
116+
private[config] def withFallbackOriginDescription(originDescription: String) =
117+
if (this.originDescription == null)
118+
setOriginDescription(originDescription)
119+
else
120+
this
121+
122+
/**
123+
* Set to false to throw an exception if the item being parsed (for example a
124+
* file) is missing. Set to true to just return an empty document in that
125+
* case. Note that this setting applies on only to fetching the root document,
126+
* it has no effect on any nested includes.
127+
*
128+
* @param allowMissing
129+
* true to silently ignore missing item
130+
* @return
131+
* options with the "allow missing" flag set
132+
*/
133+
def setAllowMissing(allowMissing: Boolean): ConfigParseOptions =
134+
if (this.allowMissing == allowMissing)
135+
this
136+
else
137+
new ConfigParseOptions(
138+
this.syntax,
139+
this.originDescription,
140+
allowMissing,
141+
this.includer,
142+
this.classLoader
143+
)
144+
145+
/**
146+
* Gets the current "allow missing" flag.
147+
*
148+
* @return
149+
* whether we allow missing files
150+
*/
151+
def getAllowMissing: Boolean = allowMissing
152+
153+
/**
154+
* Set a [[ConfigIncluder]] which customizes how includes are handled. null
155+
* means to use the default includer.
156+
*
157+
* @param includer
158+
* the includer to use or null for default
159+
* @return
160+
* new version of the parse options with different includer
161+
*/
162+
def setIncluder(includer: ConfigIncluder): ConfigParseOptions =
163+
if (this.includer == includer)
164+
this
165+
else
166+
new ConfigParseOptions(
167+
this.syntax,
168+
this.originDescription,
169+
this.allowMissing,
170+
includer,
171+
this.classLoader
172+
)
173+
174+
/**
175+
* Prepends a [[ConfigIncluder]] which customizes how includes are handled. To
176+
* prepend your includer, the library calls [[ConfigIncluder#withFallback]] on
177+
* your includer to append the existing includer to it.
178+
*
179+
* @param includer
180+
* the includer to prepend (may not be null)
181+
* @return
182+
* new version of the parse options with different includer
183+
*/
184+
def prependIncluder(includer: ConfigIncluder): ConfigParseOptions = {
185+
if (includer == null)
186+
throw new NullPointerException("null includer passed to prependIncluder")
187+
if (this.includer eq includer)
188+
this
189+
else if (this.includer != null)
190+
setIncluder(includer.withFallback(this.includer))
191+
else
192+
setIncluder(includer)
193+
}
194+
195+
/**
196+
* Appends a [[ConfigIncluder]] which customizes how includes are handled. To
197+
* append, the library calls [[ConfigIncluder#withFallback]] on the existing
198+
* includer.
199+
*
200+
* @param includer
201+
* the includer to append (may not be null)
202+
* @return
203+
* new version of the parse options with different includer
204+
*/
205+
def appendIncluder(includer: ConfigIncluder): ConfigParseOptions = {
206+
if (includer == null)
207+
throw new NullPointerException("null includer passed to appendIncluder")
208+
if (this.includer == includer)
209+
this
210+
else if (this.includer != null)
211+
setIncluder(this.includer.withFallback(includer))
212+
else
213+
setIncluder(includer)
214+
}
215+
216+
/**
217+
* Gets the current includer (will be null for the default includer).
218+
*
219+
* @return
220+
* current includer or null
221+
*/
222+
def getIncluder: ConfigIncluder = includer
223+
224+
/**
225+
* Set the class loader. If set to null,
226+
* `Thread.currentThread().getContextClassLoader()` will be used.
227+
*
228+
* @param loader
229+
* a class loader or `null` to use thread context class loader
230+
* @return
231+
* options with the class loader set
232+
*/
233+
def setClassLoader(loader: ClassLoader): ConfigParseOptions =
234+
if (this.classLoader == loader)
235+
this
236+
else
237+
new ConfigParseOptions(
238+
this.syntax,
239+
this.originDescription,
240+
this.allowMissing,
241+
this.includer,
242+
loader
243+
)
244+
245+
/**
246+
* Get the class loader; never returns `null`, if the class loader was unset,
247+
* returns `Thread.currentThread().getContextClassLoader()`.
248+
*
249+
* @return
250+
* class loader to use
251+
*/
252+
def getClassLoader: ClassLoader =
253+
if (this.classLoader == null) {
254+
val thread = Thread.currentThread
255+
new PlatformThread(thread).getContextClassLoader()
256+
} else {
257+
this.classLoader
258+
}
259+
}

0 commit comments

Comments
 (0)