You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2021/12/26 19:07:01 UTC
[juneau] branch master updated: Javadocs and Config API modernization.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 57babc4 Javadocs and Config API modernization.
57babc4 is described below
commit 57babc43e61fbd448cdcce53f046062ae28e76ca
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sun Dec 26 14:06:25 2021 -0500
Javadocs and Config API modernization.
---
.../main/java/org/apache/juneau/config/Config.java | 621 +-----------
.../java/org/apache/juneau/config/ConfigMod.java | 6 +-
.../main/java/org/apache/juneau/config/Entry.java | 872 ++++++++++++++++
.../apache/juneau/config/internal/ConfigEntry.java | 9 +
.../juneau/config/internal/package-info.java | 18 -
.../org/apache/juneau/config/vars/ConfigVar.java | 4 +-
.../org/apache/juneau/internal/StringUtils.java | 69 +-
.../06.juneau-rest-server/05.jrs.Marshalling.html | 25 +
.../{09.jrs.Guards.html => 07.jrs.Guards.html} | 40 +-
.../06.juneau-rest-server/07.jrs.Transforms.html | 72 --
....jrs.Converters.html => 08.jrs.Converters.html} | 64 +-
...Messages.html => 09.jrs.LocalizedMessages.html} | 12 +-
.../{13.jrs.Encoders.html => 10.jrs.Encoders.html} | 6 +-
.../06.juneau-rest-server/10.jrs.RoleGuards.html | 81 --
...onFiles.html => 11.jrs.ConfigurationFiles.html} | 74 +-
....SvlVariables.html => 12.jrs.SvlVariables.html} | 0
...rs.StaticFiles.html => 13.jrs.StaticFiles.html} | 0
...ersioning.html => 14.jrs.ClientVersioning.html} | 0
....InfoProvider.html => 15.jrs.InfoProvider.html} | 0
.../{19.jrs.Swagger.html => 16.jrs.Swagger.html} | 0
.../01.jrs.BasicRestServletSwagger.html | 0
.../02.jrs.BasicSwaggerInfo.html | 0
.../03.jrs.SwaggerTags.html | 0
.../04.jrs.SwaggerOperations.html | 0
.../05.jrs.SwaggerParameters.html | 0
.../06.jrs.SwaggerParameterExamples.html | 0
.../07.jrs.SwaggerResponses.html | 0
.../08.jrs.SwaggerResponseExamples.html | 0
.../09.jrs.SwaggerModels.html | 0
.../10.jrs.SwaggerStylesheet.html | 0
.../doc-files/jrs.Swagger.Models.1.png | Bin
.../doc-files/jrs.Swagger.Models.2.png | Bin
.../doc-files/jrs.Swagger.Models.3.png | Bin
.../doc-files/jrs.Swagger.Operations.1.png | Bin
.../doc-files/jrs.Swagger.Operations.2.png | Bin
.../doc-files/jrs.Swagger.Operations.3.png | Bin
.../doc-files/jrs.Swagger.Parameters.1.png | Bin
.../doc-files/jrs.Swagger.Parameters.2.png | Bin
.../doc-files/jrs.Swagger.Parameters.3.png | Bin
.../doc-files/jrs.Swagger.Parameters.4.png | Bin
.../doc-files/jrs.Swagger.ResponseExamples.1.png | Bin
.../doc-files/jrs.Swagger.ResponseExamples.2.png | Bin
.../doc-files/jrs.Swagger.ResponseExamples.3.png | Bin
.../doc-files/jrs.Swagger.ResponseExamples.4.png | Bin
...istics.html => 17.jrs.ExecutionStatistics.html} | 0
...notation.html => 18.jrs.HtmlDocAnnotation.html} | 0
.../01.jrs.HtmlUIvsDI.html | 0
.../02.jrs.HtmlWidgets.html | 0
.../03.jrs.HtmlPredefinedWidgets.html | 0
.../04.jrs.HtmlUiCustomization.html | 0
.../05.jrs.HtmlStylesheets.html | 0
.../jrs.HtmlDocAnnotation.PredefinedWidgets.1.png | Bin
.../jrs.HtmlDocAnnotation.PredefinedWidgets.2.png | Bin
.../jrs.HtmlDocAnnotation.PredefinedWidgets.3.png | Bin
.../jrs.HtmlDocAnnotation.PredefinedWidgets.4.png | Bin
...aultHeaders.html => 19.jrs.DefaultHeaders.html} | 0
...ugging.html => 20.jrs.LoggingAndDebugging.html} | 0
...tatusCodes.html => 21.jrs.HttpStatusCodes.html} | 0
...ods.html => 22.jrs.OverloadingHttpMethods.html} | 0
...rameters.html => 23.jrs.BuiltInParameters.html} | 0
...tml => 24.jrs.CustomSerializersAndParsers.html} | 0
...singWithOsgi.html => 25.jrs.UsingWithOsgi.html} | 0
...29.jrs.Injection.html => 26.jrs.Injection.html} | 0
....jrs.OtherNotes.html => 27.jrs.OtherNotes.html} | 0
...rs.RestContext.html => 28.jrs.RestContext.html} | 0
.../{32.jrs.RestRpc.html => 29.jrs.RestRpc.html} | 0
...l => 30.jrs.CustomRestContextsAndBuilders.html} | 0
...rocessors.html => 31.jrs.FluentAssertions.html} | 0
....jrs.UtilityBeans.html => 32.jrs.Overview.html} | 0
...ertions.html => 33.jrs.ResponseProcessors.html} | 0
....jrs.Overview.html => 34.jrs.UtilityBeans.html} | 0
...ndlingUris.html => 35.jrs.SerializingUris.html} | 0
juneau-doc/src/main/javadoc/overview.html | 1062 +++++++++-----------
juneau-doc/src/main/javadoc/resources/docs.txt | 6 +-
.../src/main/javadoc/resources/fragments/toc.html | 14 +-
.../apache/juneau/microservice/Microservice.java | 33 +-
.../juneau/microservice/console/ConfigCommand.java | 4 +-
.../microservice/resources/DirectoryResource.java | 8 +-
.../microservice/resources/LogsResource.java | 10 +-
.../apache/juneau/rest/test/ConfigResource.java | 2 +-
.../apache/juneau/rest/test/TestMicroservice.java | 2 +-
.../microservice/jetty/JettyMicroservice.java | 12 +-
.../jetty/resources/DebugResource.java | 2 +-
.../rest/springboot/BasicSpringRestServlet.java | 2 +-
.../org/apache/juneau/rest/BasicRestObject.java | 2 +-
.../org/apache/juneau/rest/BasicRestServlet.java | 2 +-
.../server/config/repository/GetConfiguration.java | 4 +-
.../apache/juneau/config/ConfigImportsTest.java | 72 +-
.../apache/juneau/config/ConfigInterfaceTest.java | 94 +-
.../java/org/apache/juneau/config/ConfigTest.java | 592 +++++------
90 files changed, 1941 insertions(+), 1955 deletions(-)
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 2f2808b..33ce5f4 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -545,10 +545,10 @@ public final class Config extends Context implements ConfigEventListener {
final int binaryLineLength;
final BinaryFormat binaryFormat;
final boolean multiLineValuesOnSeparateLines, readOnly;
+ final BeanSession beanSession;
+ final VarResolverSession varSession;
- private final VarResolverSession varSession;
private final ConfigMap configMap;
- private final BeanSession beanSession;
private final List<ConfigEventListener> listeners = Collections.synchronizedList(new LinkedList<ConfigEventListener>());
@@ -640,7 +640,7 @@ public final class Config extends Context implements ConfigEventListener {
* @param key The key.
* @return The value, or <jk>null</jk> if the section or value doesn't exist.
*/
- public String get(String key) {
+ private String getRaw(String key) {
String sname = sname(key);
String skey = skey(key);
@@ -651,7 +651,7 @@ public final class Config extends Context implements ConfigEventListener {
return null;
String val = ce.getValue();
- for (ConfigMod m : ConfigMod.asModifiersReverse(ce.getModifiers())) {
+ for (ConfigMod m : ConfigMod.toReverse(ce.getModifiers())) {
if (m == ENCODED) {
if (encoder.isEncoded(val))
val = encoder.decode(key, val);
@@ -674,7 +674,7 @@ public final class Config extends Context implements ConfigEventListener {
for (String section : getSections()) {
for (String key : getKeys(section)) {
String k = (section.isEmpty() ? key : section + '/' + key);
- System.setProperty(k, get(k));
+ System.setProperty(k, getRaw(k));
}
}
return this;
@@ -705,7 +705,7 @@ public final class Config extends Context implements ConfigEventListener {
String mod = ce == null ? "" : ce.getModifiers();
String s = stringify(value);
- for (ConfigMod m : ConfigMod.asModifiers(mod)) {
+ for (ConfigMod m : ConfigMod.toModifiers(mod)) {
if (m == ENCODED) {
s = encoder.encode(key, s);
}
@@ -814,7 +814,7 @@ public final class Config extends Context implements ConfigEventListener {
}
}
- configMap.setEntry(sname, skey, s, modifiers == null ? null : ConfigMod.asString(modifiers), comment, preLines);
+ configMap.setEntry(sname, skey, s, modifiers == null ? null : ConfigMod.toModString(modifiers), comment, preLines);
return this;
}
@@ -873,557 +873,14 @@ public final class Config extends Context implements ConfigEventListener {
* <js>"section/key"</js> - A value from the specified section.
* </ul>
*
- * @param key The key.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public String getString(String key) {
- String s = get(key);
- if (s == null)
- return null;
- if (varSession != null)
- s = varSession.resolve(s);
- return s;
- }
-
- /**
- * Gets the entry with the specified key.
- *
- * <p>
- * The key can be in one of the following formats...
- * <ul class='spaced-list'>
- * <li>
- * <js>"key"</js> - A value in the default section (i.e. defined above any <c>[section]</c> header).
- * <li>
- * <js>"section/key"</js> - A value from the specified section.
- * </ul>
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the section or key does not exist.
- */
- public String getString(String key, String def) {
- String s = get(key);
- if (isEmpty(s))
- return def;
- if (varSession != null)
- s = varSession.resolve(s);
- return s;
- }
-
- /**
- * Gets the entry with the specified key, splits the value on commas, and returns the values as trimmed strings.
- *
- * @param key The key.
- * @return The value, or an empty array if the section or key does not exist.
- */
- public String[] getStringArray(String key) {
- return getStringArray(key, new String[0]);
- }
-
- /**
- * Same as {@link #getStringArray(String)} but returns a default value if the value cannot be found.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the section or key does not exist or is blank.
- */
- public String[] getStringArray(String key, String[] def) {
- String s = getString(key);
- if (isEmpty(s))
- return def;
- String[] r = split(s);
- return r.length == 0 ? def : r;
- }
-
- /**
- * Convenience method for getting int config values.
- *
- * <p>
- * <js>"K"</js>, <js>"M"</js>, and <js>"G"</js> can be used to identify kilo, mega, and giga.
- *
- * <h5 class='section'>Example:</h5>
- * <ul class='spaced-list'>
- * <li>
- * <code><js>"100K"</js> => 1024000</code>
- * <li>
- * <code><js>"100M"</js> => 104857600</code>
- * </ul>
- *
- * <p>
- * Uses {@link Integer#decode(String)} underneath, so any of the following integer formats are supported:
- * <ul>
- * <li><js>"0x..."</js>
- * <li><js>"0X..."</js>
- * <li><js>"#..."</js>
- * <li><js>"0..."</js>
- * </ul>
- *
- * @param key The key.
- * @return The value, or <c>0</c> if the value does not exist or the value is empty.
- */
- public int getInt(String key) {
- return getInt(key, 0);
- }
-
- /**
- * Same as {@link #getInt(String)} but returns a default value if not set.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the value does not exist or the value is empty.
- */
- public int getInt(String key, int def) {
- String s = getString(key);
- if (isEmpty(s))
- return def;
- return parseIntWithSuffix(s);
- }
-
- /**
- * Convenience method for getting boolean config values.
- *
- * @param key The key.
- * @return The value, or <jk>false</jk> if the section or key does not exist or cannot be parsed as a boolean.
- */
- public boolean getBoolean(String key) {
- return getBoolean(key, false);
- }
-
- /**
- * Convenience method for getting boolean config values.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the section or key does not exist or cannot be parsed as a boolean.
- */
- public boolean getBoolean(String key, boolean def) {
- String s = getString(key);
- return isEmpty(s) ? def : Boolean.parseBoolean(s);
- }
-
- /**
- * Convenience method for getting long config values.
- *
- * <p>
- * <js>"K"</js>, <js>"M"</js>, and <js>"G"</js> can be used to identify kilo, mega, and giga.
- *
- * <h5 class='section'>Example:</h5>
- * <ul class='spaced-list'>
- * <li>
- * <code><js>"100K"</js> => 1024000</code>
- * <li>
- * <code><js>"100M"</js> => 104857600</code>
- * </ul>
- *
- * <p>
- * Uses {@link Long#decode(String)} underneath, so any of the following number formats are supported:
- * <ul>
- * <li><js>"0x..."</js>
- * <li><js>"0X..."</js>
- * <li><js>"#..."</js>
- * <li><js>"0..."</js>
- * </ul>
- *
- * @param key The key.
- * @return The value, or <c>0</c> if the value does not exist or the value is empty.
- */
- public long getLong(String key) {
- return getLong(key, 0);
- }
-
- /**
- * Same as {@link #getLong(String)} but returns a default value if not set.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the value does not exist or the value is empty.
- */
- public long getLong(String key, long def) {
- String s = getString(key);
- if (isEmpty(s))
- return def;
- return parseLongWithSuffix(s);
- }
-
- /**
- * Convenience method for getting double config values.
- *
- * <p>
- * Uses {@link Double#valueOf(String)} underneath, so any of the following number formats are supported:
- * <ul>
- * <li><js>"0x..."</js>
- * <li><js>"0X..."</js>
- * <li><js>"#..."</js>
- * <li><js>"0..."</js>
- * </ul>
- *
- * @param key The key.
- * @return The value, or <c>0</c> if the value does not exist or the value is empty.
- */
- public double getDouble(String key) {
- return getDouble(key, 0);
- }
-
- /**
- * Same as {@link #getDouble(String)} but returns a default value if not set.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the value does not exist or the value is empty.
- */
- public double getDouble(String key, double def) {
- String s = getString(key);
- if (isEmpty(s))
- return def;
- return Double.valueOf(s);
- }
-
- /**
- * Convenience method for getting float config values.
- *
- * <p>
- * Uses {@link Float#valueOf(String)} underneath, so any of the following number formats are supported:
- * <ul>
- * <li><js>"0x..."</js>
- * <li><js>"0X..."</js>
- * <li><js>"#..."</js>
- * <li><js>"0..."</js>
- * </ul>
- *
- * @param key The key.
- * @return The value, or <c>0</c> if the value does not exist or the value is empty.
- */
- public float getFloat(String key) {
- return getFloat(key, 0);
- }
-
- /**
- * Same as {@link #getFloat(String)} but returns a default value if not set.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the value does not exist or the value is empty.
- */
- public float getFloat(String key, float def) {
- String s = getString(key);
- if (isEmpty(s))
- return def;
- return Float.valueOf(s);
- }
-
- /**
- * Convenience method for getting byte array config values.
- *
- * <p>
- * This is equivalent to calling the following:
- * <p class='bcode w800'>
- * <jk>byte</jk>[] b = config.getObject(key, <jk>byte</jk>[].<jk>class</jk>);
- * </p>
- *
- * <p>
- * Byte arrays are stored as encoded strings, typically BASE64, but dependent on the {@link Builder#binaryFormat(BinaryFormat)} setting.
- *
- * @param key The key.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- * @throws ParseException If value could not be converted to a byte array.
- */
- public byte[] getBytes(String key) throws ParseException {
- String s = get(key);
- if (s == null)
- return null;
- if (s.isEmpty())
- return new byte[0];
- return getObject(key, byte[].class);
- }
-
- /**
- * Same as {@link #getBytes(String)} but with a default value if the entry doesn't exist.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @return The value, or the default value if the section or key does not exist.
- * @throws ParseException If value could not be converted to a byte array.
- */
- public byte[] getBytes(String key, byte[] def) throws ParseException {
- String s = get(key);
- if (s == null)
- return def;
- if (s.isEmpty())
- return def;
- return getObjectWithDefault(key, def, byte[].class);
- }
-
- /**
- * Gets the entry with the specified key and converts it to the specified value.
- *
- * <p>
- * The key can be in one of the following formats...
- * <ul class='spaced-list'>
- * <li>
- * <js>"key"</js> - A value in the default section (i.e. defined above any <c>[section]</c> header).
- * <li>
- * <js>"section/key"</js> - A value from the specified section.
- * </ul>
- *
- * <p>
- * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bcode w800'>
- * Config cf = Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
- *
- * <jc>// Parse into a linked-list of strings.</jc>
- * List l = cf.getObject(<js>"MySection/myListOfStrings"</js>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
- *
- * <jc>// Parse into a linked-list of beans.</jc>
- * List l = cf.getObject(<js>"MySection/myListOfBeans"</js>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
- *
- * <jc>// Parse into a linked-list of linked-lists of strings.</jc>
- * List l = cf.getObject(<js>"MySection/my2dListOfStrings"</js>, LinkedList.<jk>class</jk>,
- * LinkedList.<jk>class</jk>, String.<jk>class</jk>);
- *
- * <jc>// Parse into a map of string keys/values.</jc>
- * Map m = cf.getObject(<js>"MySection/myMap"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>,
- * String.<jk>class</jk>);
- *
- * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
- * Map m = cf.getObject(<js>"MySection/myMapOfListsOfBeans"</js>, TreeMap.<jk>class</jk>, String.<jk>class</jk>,
- * List.<jk>class</jk>, MyBean.<jk>class</jk>);
- * </p>
- *
- * <p>
- * <c>Collection</c> classes are assumed to be followed by zero or one objects indicating the element type.
- *
- * <p>
- * <c>Map</c> classes are assumed to be followed by zero or two meta objects indicating the key and value
- * types.
- *
- * <p>
- * The array can be arbitrarily long to indicate arbitrarily complex data structures.
- *
- * <ul class='notes'>
- * <li>
- * Use the {@link #getObject(String, Class)} method instead if you don't need a parameterized map/collection.
- * </ul>
- *
- * @param key The key.
- * @param type
- * The object type to create.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * @param args
- * The type arguments of the class if it's a collection or map.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * <br>Ignored if the main type is not a map or collection.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public <T> T getObject(String key, Type type, Type...args) throws ParseException {
- return getObject(key, (Parser)null, type, args);
- }
-
- /**
- * Same as {@link #getObject(String, Type, Type...)} but allows you to specify the parser to use to parse the value.
- *
- * @param key The key.
- * @param parser
- * The parser to use for parsing the object.
- * If <jk>null</jk>, then uses the predefined parser on the config file.
- * @param type
- * The object type to create.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * @param args
- * The type arguments of the class if it's a collection or map.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * <br>Ignored if the main type is not a map or collection.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public <T> T getObject(String key, Parser parser, Type type, Type...args) throws ParseException {
- assertArgNotNull("type", type);
- return parse(getString(key), parser, type, args);
- }
-
- /**
- * Same as {@link #getObject(String, Type, Type...)} except optimized for a non-parameterized class.
- *
- * <p>
- * This is the preferred parse method for simple types since you don't need to cast the results.
- *
- * <h5 class='section'>Examples:</h5>
- * <p class='bcode w800'>
- * Config cf = Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
- *
- * <jc>// Parse into a string.</jc>
- * String s = cf.getObject(<js>"MySection/mySimpleString"</js>, String.<jk>class</jk>);
- *
- * <jc>// Parse into a bean.</jc>
- * MyBean b = cf.getObject(<js>"MySection/myBean"</js>, MyBean.<jk>class</jk>);
- *
- * <jc>// Parse into a bean array.</jc>
- * MyBean[] b = cf.getObject(<js>"MySection/myBeanArray"</js>, MyBean[].<jk>class</jk>);
- *
- * <jc>// Parse into a linked-list of objects.</jc>
- * List l = cf.getObject(<js>"MySection/myList"</js>, LinkedList.<jk>class</jk>);
- *
- * <jc>// Parse into a map of object keys/values.</jc>
- * Map m = cf.getObject(<js>"MySection/myMap"</js>, TreeMap.<jk>class</jk>);
- * </p>
- *
- * @param <T> The class type of the object being created.
- * @param key The key.
- * @param type The object type to create.
- * @return The parsed object.
- * @throws ParseException Malformed input encountered.
- * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
- */
- public <T> T getObject(String key, Class<T> type) throws ParseException {
- return getObject(key, (Parser)null, type);
- }
-
- /**
- * Same as {@link #getObject(String, Class)} but allows you to specify the parser to use to parse the value.
- *
- * @param <T> The class type of the object being created.
- * @param key The key.
- * @param parser
- * The parser to use for parsing the object.
- * If <jk>null</jk>, then uses the predefined parser on the config file.
- * @param type The object type to create.
- * @return The parsed object.
- * @throws ParseException Malformed input encountered.
- * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections.
- */
- public <T> T getObject(String key, Parser parser, Class<T> type) throws ParseException {
- assertArgNotNull("c", type);
- return parse(getString(key), parser, type);
- }
-
- /**
- * Gets the entry with the specified key and converts it to the specified value.
- *
- * <p>
- * Same as {@link #getObject(String, Class)}, but with a default value.
- *
- * @param key The key.
- * @param def The default value if the value does not exist.
- * @param type The class to convert the value to.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public <T> T getObjectWithDefault(String key, T def, Class<T> type) throws ParseException {
- return getObjectWithDefault(key, null, def, type);
- }
-
- /**
- * Same as {@link #getObjectWithDefault(String, Object, Class)} but allows you to specify the parser to use to parse
- * the value.
- *
- * @param key The key.
- * @param parser
- * The parser to use for parsing the object.
- * If <jk>null</jk>, then uses the predefined parser on the config file.
- * @param def The default value if the value does not exist.
- * @param type The class to convert the value to.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public <T> T getObjectWithDefault(String key, Parser parser, T def, Class<T> type) throws ParseException {
- assertArgNotNull("type", type);
- T t = parse(getString(key), parser, type);
- return (t == null ? def : t);
- }
-
- /**
- * Gets the entry with the specified key and converts it to the specified value.
- *
* <p>
- * Same as {@link #getObject(String, Type, Type...)}, but with a default value.
+ * If entry does not exist, returns an empty {@link Entry} object.
*
* @param key The key.
- * @param def The default value if the value does not exist.
- * @param type
- * The object type to create.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * @param args
- * The type arguments of the class if it's a collection or map.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * <br>Ignored if the main type is not a map or collection.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @return The value, never <jk>null</jk>.
*/
- public <T> T getObjectWithDefault(String key, T def, Type type, Type...args) throws ParseException {
- return getObjectWithDefault(key, null, def, type, args);
- }
-
- /**
- * Same as {@link #getObjectWithDefault(String, Object, Type, Type...)} but allows you to specify the parser to use
- * to parse the value.
- *
- * @param key The key.
- * @param parser
- * The parser to use for parsing the object.
- * If <jk>null</jk>, then uses the predefined parser on the config file.
- * @param def The default value if the value does not exist.
- * @param type
- * The object type to create.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * @param args
- * The type arguments of the class if it's a collection or map.
- * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
- * <br>Ignored if the main type is not a map or collection.
- * @throws ParseException If parser could not parse the value or if a parser is not registered with this config file.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- */
- public <T> T getObjectWithDefault(String key, Parser parser, T def, Type type, Type...args) throws ParseException {
- assertArgNotNull("type", type);
- T t = parse(getString(key), parser, type, args);
- return (t == null ? def : t);
- }
-
- /**
- * Convenience method for returning a config entry as an {@link OMap}.
- *
- * @param key The key.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- * @throws ParseException Malformed input encountered.
- */
- public OMap getMap(String key) throws ParseException {
- return getObject(key, OMap.class);
- }
-
- /**
- * Convenience method for returning a config entry as an {@link OMap}.
- *
- * @param key The key.
- * @param def The default value.
- * @return The value, or the default value if the section or key does not exist.
- * @throws ParseException Malformed input encountered.
- */
- public OMap getMap(String key, OMap def) throws ParseException {
- return getObjectWithDefault(key, def, OMap.class);
- }
-
- /**
- * Convenience method for returning a config entry as an {@link OList}.
- *
- * @param key The key.
- * @return The value, or <jk>null</jk> if the section or key does not exist.
- * @throws ParseException Malformed input encountered.
- */
- public OList getList(String key) throws ParseException {
- return getObject(key, OList.class);
- }
-
- /**
- * Convenience method for returning a config entry as an {@link OList}.
- *
- * @param key The key.
- * @param def The default value.
- * @return The value, or the default value if the section or key does not exist.
- * @throws ParseException Malformed input encountered.
- */
- public OList getList(String key, OList def) throws ParseException {
- return getObjectWithDefault(key, def, OList.class);
+ public Entry get(String key) {
+ return new Entry(this, configMap, sname(key), skey(key));
}
/**
@@ -1471,7 +928,7 @@ public final class Config extends Context implements ConfigEventListener {
if (! ignoreUnknownProperties)
throw new ParseException("Unknown property ''{0}'' encountered in configuration section ''{1}''.", k, section);
} else {
- bm.put(k, getObject(section + '/' + k, bpm.getClassMeta().getInnerClass()));
+ bm.put(k, get(section + '/' + k).as(bpm.getClassMeta().getInnerClass()).orElse(null));
}
}
@@ -1551,7 +1008,7 @@ public final class Config extends Context implements ConfigEventListener {
if (! ignoreUnknownProperties)
throw new ParseException("Unknown property ''{0}'' encountered in configuration section ''{1}''.", k, section);
} else {
- bm.put(k, getObject(section + '/' + k, bpm.getClassMeta().getInnerClass()));
+ bm.put(k, get(section + '/' + k).as(bpm.getClassMeta().getInnerClass()).orElse(null));
}
}
@@ -1578,7 +1035,7 @@ public final class Config extends Context implements ConfigEventListener {
OMap om = new OMap();
for (String k : keys)
- om.put(k, getObject(section + '/' + k, Object.class));
+ om.put(k, get(section + '/' + k).as(Object.class).orElse(null));
return om;
}
@@ -1670,7 +1127,7 @@ public final class Config extends Context implements ConfigEventListener {
for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
Method rm = pd.getReadMethod(), wm = pd.getWriteMethod();
if (method.equals(rm))
- return Config.this.getObject(section2 + '/' + pd.getName(), rm.getGenericReturnType());
+ return Config.this.get(section2 + '/' + pd.getName()).to(rm.getGenericReturnType());
if (method.equals(wm))
return Config.this.set(section2 + '/' + pd.getName(), args[0]);
}
@@ -1688,7 +1145,7 @@ public final class Config extends Context implements ConfigEventListener {
* @return <jk>true</jk> if this section contains the specified key and the key has a non-blank value.
*/
public boolean exists(String key) {
- return isNotEmpty(getString(key, null));
+ return isNotEmpty(get(key).as(String.class).orElse(null));
}
/**
@@ -2000,43 +1457,6 @@ public final class Config extends Context implements ConfigEventListener {
return s;
}
- @SuppressWarnings({ "unchecked" })
- private <T> T parse(String s, Parser parser, Type type, Type...args) throws ParseException {
-
- if (isEmpty(s))
- return null;
-
- if (isSimpleType(type))
- return (T)beanSession.convertToType(s, (Class<?>)type);
-
- if (type == byte[].class) {
- if (s.indexOf('\n') != -1)
- s = s.replaceAll("\n", "");
- try {
- switch (binaryFormat) {
- case HEX: return (T)fromHex(s);
- case SPACED_HEX: return (T)fromSpacedHex(s);
- default: return (T)base64Decode(s);
- }
- } catch (Exception e) {
- throw new ParseException(e, "Value could not be converted to a byte array.");
- }
- }
-
- if (parser == null)
- parser = this.parser;
-
- if (parser instanceof JsonParser) {
- char s1 = firstNonWhitespaceChar(s);
- if (isArray(type) && s1 != '[')
- s = '[' + s + ']';
- else if (s1 != '[' && s1 != '{' && ! "null".equals(s))
- s = '\'' + s + '\'';
- }
-
- return parser.parse(s, type, args);
- }
-
private boolean isSimpleType(Type t) {
if (! (t instanceof Class))
return false;
@@ -2044,13 +1464,6 @@ public final class Config extends Context implements ConfigEventListener {
return (c == String.class || c.isPrimitive() || c.isAssignableFrom(Number.class) || c == Boolean.class || c.isEnum());
}
- private boolean isArray(Type t) {
- if (! (t instanceof Class))
- return false;
- Class<?> c = (Class<?>)t;
- return (c.isArray());
- }
-
private String sname(String key) {
assertArgNotNull("key", key);
int i = key.indexOf('/');
@@ -2073,7 +1486,7 @@ public final class Config extends Context implements ConfigEventListener {
return section;
}
- private void checkWrite() {
+ void checkWrite() {
if (readOnly)
throw unsupportedOperationException("Cannot call this method on a read-only configuration.");
}
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/ConfigMod.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/ConfigMod.java
index b4be485..716091b 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/ConfigMod.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/ConfigMod.java
@@ -45,7 +45,7 @@ public enum ConfigMod {
* @param mods The modifiers.
* @return A modifier string, or an empty string if there are no modifiers.
*/
- public static String asString(ConfigMod...mods) {
+ public static String toModString(ConfigMod...mods) {
if (mods.length == 0)
return "";
if (mods.length == 1)
@@ -69,7 +69,7 @@ public enum ConfigMod {
* @param s The modifier string.
* @return The list of modifiers, or an empty list if the string is empty or <jk>null</jk>.
*/
- public static List<ConfigMod> asModifiersReverse(String s) {
+ public static List<ConfigMod> toReverse(String s) {
if (isEmpty(s))
return Collections.emptyList();
if (s.length() == 1) {
@@ -91,7 +91,7 @@ public enum ConfigMod {
* @param s The modifier string.
* @return The list of modifiers, or an empty list if the string is empty or <jk>null</jk>.
*/
- public static List<ConfigMod> asModifiers(String s) {
+ public static List<ConfigMod> toModifiers(String s) {
if (isEmpty(s))
return Collections.emptyList();
if (s.length() == 1) {
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Entry.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Entry.java
new file mode 100644
index 0000000..b6eba19
--- /dev/null
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Entry.java
@@ -0,0 +1,872 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you 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. *
+// ***************************************************************************************************************************
+package org.apache.juneau.config;
+
+import static org.apache.juneau.config.ConfigMod.*;
+import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.BinaryFormat.*;
+import static java.util.Optional.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.function.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.collections.*;
+import org.apache.juneau.config.internal.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * A single entry in a {@link Config} file.
+ */
+public class Entry {
+
+ private final ConfigEntry configEntry;
+ private final Config config;
+ private final String value;
+
+ /**
+ * Constructor.
+ *
+ * @param config The config that this entry belongs to.
+ * @param configMap The map that this belongs to.
+ * @param sectionName The section name of this entry.
+ * @param entryName The name of this entry.
+ */
+ protected Entry(Config config, ConfigMap configMap, String sectionName, String entryName) {
+ this.configEntry = configMap.getEntry(sectionName, entryName);
+ this.config = config;
+
+ String v = null;
+ if (configEntry != null) {
+ v = configEntry.getValue();
+ if (! StringUtils.isEmpty(configEntry.getModifiers()))
+ for (ConfigMod m : ConfigMod.toReverse(configEntry.getModifiers()))
+ if (m == ENCODED)
+ if (config.encoder.isEncoded(v))
+ v = config.encoder.decode(configEntry.getKey(), v);
+ }
+ this.value = v;
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // Value retrievers
+ //-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Returns <jk>true</jk> if this entry exists in the config.
+ *
+ * @return <jk>true</jk> if this entry exists in the config.
+ */
+ public boolean isPresent() {
+ return ! isNull();
+ }
+
+ /**
+ * Returns <jk>true</jk> if this entry exists in the config and is not empty.
+ *
+ * @return <jk>true</jk> if this entry exists in the config and is not empty.
+ */
+ public boolean isNotEmpty() {
+ return ! isEmpty();
+ }
+
+ /**
+ * Returns this entry as a string.
+ *
+ * @return <jk>true</jk> if this entry exists in the config and is not empty.
+ * @throws NullPointerException if value was <jk>null</jk>.
+ */
+ public String get() {
+ if (isNull()) throw new NullPointerException("Value was null");
+ return toString();
+ }
+
+ /**
+ * Returns this entry converted to the specified type.
+ *
+ * @param type The type to convert the value to.
+ * @return This entry converted to the specified type.
+ */
+ public <T> Optional<T> as(Class<T> type) {
+ return ofNullable(to((Type)type));
+ }
+
+ /**
+ * Returns this entry converted to the specified type.
+ *
+ * @param parser The parser to use to parse the entry value.
+ * @param type The type to convert the value to.
+ * @return This entry converted to the specified type.
+ */
+ public <T> Optional<T> as(Parser parser, Class<T> type) {
+ return ofNullable(to(parser, (Type)type));
+ }
+
+ /**
+ * Returns this entry converted to the specified type or returns the default value.
+ *
+ * <p>
+ * This is equivalent to calling <c>as(<jv>def</jv>.getClass()).orElse(<jv>def</jv>)</c> but is simpler and
+ * avoids the creation of an {@link Optional} object.
+ *
+ * @param def The default value to return if value does not exist.
+ * @return This entry converted to the specified type or returns the default value.
+ */
+ public String orElse(String def) {
+ return isNull() ? def : get();
+ }
+
+ /**
+ * Returns this entry converted to the specified type or returns the default value.
+ *
+ * <p>
+ * This is equivalent to calling <c>as(<jv>def</jv>.getClass()).orElse(<jv>def</jv>)</c> but is simpler and
+ * avoids the creation of an {@link Optional} object.
+ *
+ * @param def The default value to return if value does not exist.
+ * @return This entry converted to the specified type or returns the default value.
+ */
+ public String orElseGet(Supplier<String> def) {
+ return isNull() ? def.get() : get();
+ }
+
+ /**
+ * Returns this entry converted to the specified type.
+ *
+ * @param type The type to convert the value to.
+ * @return This entry converted to the specified type.
+ */
+ public <T> T to(Class<T> type) {
+ return to((Type)type);
+ }
+
+ /**
+ * Returns this entry converted to the specified value.
+ *
+ * <p>
+ * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
+ *
+ * <h5 class='section'>Examples:</h5>
+ * <p class='bcode w800'>
+ * Config cf = Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
+ *
+ * <jc>// Parse into a linked-list of strings.</jc>
+ * List l = cf.get(<js>"MySection/myListOfStrings"</js>).to(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a linked-list of beans.</jc>
+ * List l = cf.get(<js>"MySection/myListOfBeans"</js>).to(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+ *
+ * <jc>// Parse into a linked-list of linked-lists of strings.</jc>
+ * List l = cf.get(<js>"MySection/my2dListOfStrings"</js>).to(LinkedList.<jk>class</jk>,
+ * LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a map of string keys/values.</jc>
+ * Map m = cf.get(<js>"MySection/myMap"</js>).to(TreeMap.<jk>class</jk>, String.<jk>class</jk>,
+ * String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
+ * Map m = cf.get(<js>"MySection/myMapOfListsOfBeans"</js>).to(TreeMap.<jk>class</jk>, String.<jk>class</jk>,
+ * List.<jk>class</jk>, MyBean.<jk>class</jk>);
+ * </p>
+ *
+ * <p>
+ * <c>Collection</c> classes are assumed to be followed by zero or one objects indicating the element type.
+ *
+ * <p>
+ * <c>Map</c> classes are assumed to be followed by zero or two meta objects indicating the key and value
+ * types.
+ *
+ * <p>
+ * The array can be arbitrarily long to indicate arbitrarily complex data structures.
+ *
+ * <ul class='notes'>
+ * <li>
+ * Use the {@link #to(Class)} method instead if you don't need a parameterized map/collection.
+ * </ul>
+ *
+ * @param type
+ * The object type to create.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * @param args
+ * The type arguments of the class if it's a collection or map.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * <br>Ignored if the main type is not a map or collection.
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ */
+ public <T> T to(Type type, Type...args) {
+ return to(config.parser, type, args);
+ }
+
+ /**
+ * Returns this entry converted to the specified value.
+ *
+ * <p>
+ * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps).
+ *
+ * <h5 class='section'>Examples:</h5>
+ * <p class='bcode w800'>
+ * Config cf = Config.<jsm>create</jsm>().name(<js>"MyConfig.cfg"</js>).build();
+ *
+ * <jc>// Parse into a linked-list of strings.</jc>
+ * List l = cf.get(<js>"MySection/myListOfStrings"</js>).to(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a linked-list of beans.</jc>
+ * List l = cf.get(<js>"MySection/myListOfBeans"</js>).to(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+ *
+ * <jc>// Parse into a linked-list of linked-lists of strings.</jc>
+ * List l = cf.get(<js>"MySection/my2dListOfStrings"</js>).to(LinkedList.<jk>class</jk>,
+ * LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a map of string keys/values.</jc>
+ * Map m = cf.get(<js>"MySection/myMap"</js>).to(TreeMap.<jk>class</jk>, String.<jk>class</jk>,
+ * String.<jk>class</jk>);
+ *
+ * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
+ * Map m = cf.get(<js>"MySection/myMapOfListsOfBeans"</js>).to(TreeMap.<jk>class</jk>, String.<jk>class</jk>,
+ * List.<jk>class</jk>, MyBean.<jk>class</jk>);
+ * </p>
+ *
+ * <p>
+ * <c>Collection</c> classes are assumed to be followed by zero or one objects indicating the element type.
+ *
+ * <p>
+ * <c>Map</c> classes are assumed to be followed by zero or two meta objects indicating the key and value
+ * types.
+ *
+ * <p>
+ * The array can be arbitrarily long to indicate arbitrarily complex data structures.
+ *
+ * <ul class='notes'>
+ * <li>
+ * Use the {@link #to(Class)} method instead if you don't need a parameterized map/collection.
+ * </ul>
+ *
+ * @param type
+ * The object type to create.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * @param args
+ * The type arguments of the class if it's a collection or map.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * <br>Ignored if the main type is not a map or collection.
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ */
+ public <T> Optional<T> as(Type type, Type...args) {
+ return ofNullable(to(type, args));
+ }
+
+ /**
+ * Same as {@link #to(Type, Type...)} but specifies the parser to use to parse the entry.
+ *
+ * @param parser
+ * The parser to use to parse the entry.
+ * @param type
+ * The object type to create.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * @param args
+ * The type arguments of the class if it's a collection or map.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * <br>Ignored if the main type is not a map or collection.
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T to(Parser parser, Type type, Type...args) {
+ if (isNull()) return null;
+
+ try {
+ String v = toString();
+ if (type == String.class) return (T)toString();
+ if (type == String[].class) return (T)toStringArray();
+ if (type == byte[].class) return (T)toBytes();
+ if (type == int.class) return (T)toInteger();
+ if (type == int.class || type == Integer.class) return (T)toInteger();
+ if (type == long.class || type == Long.class) return (T)toLong();
+ if (type == OMap.class) return (T)toMap();
+ if (type == OList.class) return (T)toList();
+ if (isEmpty()) return null;
+ if (isSimpleType(type)) return (T)config.beanSession.convertToType(v, (Class<?>)type);
+
+ if (parser instanceof JsonParser) {
+ char s1 = firstNonWhitespaceChar(v);
+ if (isArray(type) && s1 != '[')
+ v = '[' + v + ']';
+ else if (s1 != '[' && s1 != '{' && ! "null".equals(v))
+ v = '\'' + v + '\'';
+ }
+ return parser.parse(v, type, args);
+ } catch (ParseException e) {
+ throw new BeanRuntimeException(e, null, "Value could not be parsed.");
+ }
+ }
+
+ /**
+ * Same as {@link #as(Type, Type...)} but specifies the parser to use to parse the entry.
+ *
+ * @param parser
+ * The parser to use to parse the entry.
+ * @param type
+ * The object type to create.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * @param args
+ * The type arguments of the class if it's a collection or map.
+ * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType}
+ * <br>Ignored if the main type is not a map or collection.
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ */
+ public <T> Optional<T> as(Parser parser, Type type, Type...args) {
+ return ofNullable(to(parser, type, args));
+ }
+
+ /**
+ * Returns this entry as a string.
+ *
+ * @return This entry as a string, or <jk>null</jk> if the entry does not exist.
+ */
+ @Override
+ public String toString() {
+ return isPresent() ? config.varSession.resolve(value) : null;
+ }
+
+ /**
+ * Returns this entry as a string.
+ *
+ * @return This entry as a string, or {@link Optional#empty()} if the entry does not exist.
+ */
+ public Optional<String> asString() {
+ return ofNullable(toString());
+ }
+
+ /**
+ * Returns this entry as a string array.
+ *
+ * <p>
+ * If the value exists, splits the value on commas and returns the values as trimmed strings.
+ *
+ * @return This entry as a string array, or <jk>null</jk> if the entry does not exist.
+ */
+ public String[] toStringArray() {
+ if (! isPresent()) return null;
+ String v = toString();
+ char s1 = firstNonWhitespaceChar(v), s2 = lastNonWhitespaceChar(v);
+ if (s1 == '[' && s2 == ']' && config.parser instanceof JsonParser) {
+ try {
+ return config.parser.parse(v, String[].class);
+ } catch (ParseException e) {
+ throw new BeanRuntimeException(e);
+ }
+ }
+ return split(v);
+ }
+
+ /**
+ * Returns this entry as a string array.
+ *
+ * <p>
+ * If the value exists, splits the value on commas and returns the values as trimmed strings.
+ *
+ * @return This entry as a string array, or {@link Optional#empty()} if the entry does not exist.
+ */
+ public Optional<String[]> asStringArray() {
+ return ofNullable(toStringArray());
+ }
+
+ /**
+ * Returns this entry as an integer.
+ *
+ * <p>
+ * <js>"K"</js>, <js>"M"</js>, and <js>"G"</js> can be used to identify kilo, mega, and giga in base 2.
+ * <br><js>"k"</js>, <js>"m"</js>, and <js>"g"</js> can be used to identify kilo, mega, and giga in base 10.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * <code><js>"100K"</js> => 1024000</code>
+ * <li>
+ * <code><js>"100M"</js> => 104857600</code>
+ * <li>
+ * <code><js>"100k"</js> => 1000000</code>
+ * <li>
+ * <code><js>"100m"</js> => 100000000</code>
+ * </ul>
+ *
+ * <p>
+ * Uses {@link Integer#decode(String)} underneath, so any of the following integer formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or <jk>null</jk> if the value does not exist or the value is empty.
+ */
+ public Integer toInteger() {
+ return isNotEmpty() ? parseIntWithSuffix(toString()) : null;
+ }
+
+ /**
+ * Returns this entry as an integer.
+ *
+ * <p>
+ * <js>"K"</js>, <js>"M"</js>, and <js>"G"</js> can be used to identify kilo, mega, and giga in base 2.
+ * <br><js>"k"</js>, <js>"m"</js>, and <js>"g"</js> can be used to identify kilo, mega, and giga in base 10.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * <code><js>"100K"</js> => 1024000</code>
+ * <li>
+ * <code><js>"100M"</js> => 104857600</code>
+ * <li>
+ * <code><js>"100k"</js> => 1000000</code>
+ * <li>
+ * <code><js>"100m"</js> => 100000000</code>
+ * </ul>
+ *
+ * <p>
+ * Uses {@link Integer#decode(String)} underneath, so any of the following integer formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or {@link Optional#empty()} if the value does not exist or the value is empty.
+ */
+ public Optional<Integer> asInteger() {
+ return ofNullable(toInteger());
+ }
+
+ /**
+ * Returns this entry as a parsed boolean.
+ *
+ * <p>
+ * Uses {@link Boolean#parseBoolean(String)} to parse value.
+ *
+ * @return The value, or <jk>null</jk> if the value does not exist or the value is empty.
+ */
+ public Boolean toBoolean() {
+ return isNotEmpty() ? Boolean.parseBoolean(toString()) : null;
+ }
+
+ /**
+ * Returns this entry as a parsed boolean.
+ *
+ * <p>
+ * Uses {@link Boolean#parseBoolean(String)} to parse value.
+ *
+ * @return The value, or {@link Optional#empty()} if the value does not exist or the value is empty.
+ */
+ public Optional<Boolean> asBoolean() {
+ return ofNullable(toBoolean());
+ }
+
+ /**
+ * Returns this entry as a long.
+ *
+ * <p>
+ * <js>"K"</js>, <js>"M"</js>, <js>"G"</js>, <js>"T"</js>, and <js>"P"</js> can be used to identify kilo, mega, giga, tera, and penta in base 2.
+ * <br><js>"k"</js>, <js>"m"</js>, <js>"g"</js>, <js>"t"</js>, and <js>"p"</js> can be used to identify kilo, mega, giga, tera, and p in base 10.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * <code><js>"100K"</js> => 1024000</code>
+ * <li>
+ * <code><js>"100M"</js> => 104857600</code>
+ * <li>
+ * <code><js>"100k"</js> => 1000000</code>
+ * <li>
+ * <code><js>"100m"</js> => 100000000</code>
+ * </ul>
+ *
+ * <p>
+ * Uses {@link Long#decode(String)} underneath, so any of the following integer formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or <jk>null</jk> if the value does not exist or the value is empty.
+ */
+ public Long toLong() {
+ return isNotEmpty() ? parseLongWithSuffix(toString()) : null;
+ }
+
+ /**
+ * Returns this entry as a long.
+ *
+ * <p>
+ * <js>"K"</js>, <js>"M"</js>, <js>"G"</js>, <js>"T"</js>, and <js>"P"</js> can be used to identify kilo, mega, giga, tera, and penta in base 2.
+ * <br><js>"k"</js>, <js>"m"</js>, <js>"g"</js>, <js>"t"</js>, and <js>"p"</js> can be used to identify kilo, mega, giga, tera, and p in base 10.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <ul class='spaced-list'>
+ * <li>
+ * <code><js>"100K"</js> => 1024000</code>
+ * <li>
+ * <code><js>"100M"</js> => 104857600</code>
+ * <li>
+ * <code><js>"100k"</js> => 1000000</code>
+ * <li>
+ * <code><js>"100m"</js> => 100000000</code>
+ * </ul>
+ *
+ * <p>
+ * Uses {@link Long#decode(String)} underneath, so any of the following integer formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or {@link Optional#empty()} if the value does not exist or the value is empty.
+ */
+ public Optional<Long> asLong() {
+ return ofNullable(toLong());
+ }
+
+ /**
+ * Returns this entry as a double.
+ *
+ * <p>
+ * Uses {@link Double#valueOf(String)} underneath, so any of the following number formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or <jk>null</jk> if the value does not exist or the value is empty.
+ */
+ public Double toDouble() {
+ return isNotEmpty() ? Double.valueOf(toString()) : null;
+ }
+
+ /**
+ * Returns this entry as a double.
+ *
+ * <p>
+ * Uses {@link Double#valueOf(String)} underneath, so any of the following number formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or {@link Optional#empty()} if the value does not exist or the value is empty.
+ */
+ public Optional<Double> asDouble() {
+ return ofNullable(toDouble());
+ }
+
+ /**
+ * Returns this entry as a float.
+ *
+ * <p>
+ * Uses {@link Float#valueOf(String)} underneath, so any of the following number formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or <jk>null</jk> if the value does not exist or the value is empty.
+ */
+ public Float toFloat() {
+ return isNotEmpty() ? Float.valueOf(toString()) : null;
+ }
+
+ /**
+ * Returns this entry as a float.
+ *
+ * <p>
+ * Uses {@link Float#valueOf(String)} underneath, so any of the following number formats are supported:
+ * <ul>
+ * <li><js>"0x..."</js>
+ * <li><js>"0X..."</js>
+ * <li><js>"#..."</js>
+ * <li><js>"0..."</js>
+ * </ul>
+ *
+ * @return The value, or {@link Optional#empty()} if the value does not exist or the value is empty.
+ */
+ public Optional<Float> asFloat() {
+ return ofNullable(toFloat());
+ }
+
+ /**
+ * Returns this entry as a byte array.
+ *
+ * <p>
+ * Byte arrays are stored as encoded strings, typically BASE64, but dependent on the {@link Config.Builder#binaryFormat(BinaryFormat)} setting.
+ *
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ */
+ public byte[] toBytes() {
+ if (isNull()) return null;
+ String s = toString();
+ if (s.indexOf('\n') != -1) s = s.replaceAll("\n", "");
+ try {
+ if (config.binaryFormat == HEX)
+ return fromHex(s);
+ if (config.binaryFormat == SPACED_HEX)
+ return fromSpacedHex(s);
+ return base64Decode(s);
+ } catch (Exception e) {
+ throw new BeanRuntimeException(e, null, "Value could not be converted to a byte array.");
+ }
+ }
+
+ /**
+ * Returns this entry as a byte array.
+ *
+ * <p>
+ * Byte arrays are stored as encoded strings, typically BASE64, but dependent on the {@link Config.Builder#binaryFormat(BinaryFormat)} setting.
+ *
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ */
+ public Optional<byte[]> asBytes() {
+ return ofNullable(toBytes());
+ }
+
+ /**
+ * Returns this entry as a parsed map.
+ *
+ * <p>
+ * Uses the parser registered on the {@link Config} to parse the entry.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"{"</js>/<js>"}"</js> in the value are optional.
+ *
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public OMap toMap() throws ParseException {
+ return toMap(null);
+ }
+
+ /**
+ * Returns this entry as a parsed map.
+ *
+ * <p>
+ * Uses the parser registered on the {@link Config} to parse the entry.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"{"</js>/<js>"}"</js> in the value are optional.
+ *
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public Optional<OMap> asMap() throws ParseException {
+ return ofNullable(toMap());
+ }
+
+ /**
+ * Returns this entry as a parsed map.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"{"</js>/<js>"}"</js> in the value are optional.
+ *
+ * @param parser The parser to use to parse the value, or <jk>null</jk> to use the parser defined on the config.
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public OMap toMap(Parser parser) throws ParseException {
+ if (isNull()) return null;
+ if (parser == null) parser = config.parser;
+ String s = toString();
+ if (parser instanceof JsonParser) {
+ char s1 = firstNonWhitespaceChar(s);
+ if (s1 != '{' && ! "null".equals(s))
+ s = '{' + s + '}';
+ }
+ return OMap.ofText(s, parser);
+ }
+
+ /**
+ * Returns this entry as a parsed map.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"{"</js>/<js>"}"</js> in the value are optional.
+ *
+ * @param parser The parser to use to parse the value, or {@link Optional#empty()} to use the parser defined on the config.
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public Optional<OMap> asMap(Parser parser) throws ParseException {
+ return ofNullable(toMap(parser));
+ }
+
+ /**
+ * Returns this entry as a parsed list.
+ *
+ * <p>
+ * Uses the parser registered on the {@link Config} to parse the entry.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"["</js>/<js>"]"</js> in the value are optional.
+ *
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public OList toList() throws ParseException {
+ return toList(config.parser);
+ }
+
+ /**
+ * Returns this entry as a parsed list.
+ *
+ * <p>
+ * Uses the parser registered on the {@link Config} to parse the entry.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"["</js>/<js>"]"</js> in the value are optional.
+ *
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public Optional<OList> asList() throws ParseException {
+ return ofNullable(toList());
+ }
+
+ /**
+ * Returns this entry as a parsed list.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"["</js>/<js>"]"</js> in the value are optional.
+ *
+ * @param parser The parser to use to parse the value, or {@link Optional#empty()} to use the parser defined on the config.
+ * @return The value, or <jk>null</jk> if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public OList toList(Parser parser) throws ParseException {
+ if (isNull()) return null;
+ if (parser == null) parser = config.parser;
+ String s = toString();
+ if (parser instanceof JsonParser) {
+ char s1 = firstNonWhitespaceChar(s);
+ if (s1 != '[' && ! "null".equals(s))
+ s = '[' + s + ']';
+ }
+ return OList.ofText(s, parser);
+ }
+
+ /**
+ * Returns this entry as a parsed list.
+ *
+ * <p>
+ * If the parser is a JSON parser, the starting/trailing <js>"["</js>/<js>"]"</js> in the value are optional.
+ *
+ * @param parser The parser to use to parse the value, or {@link Optional#empty()} to use the parser defined on the config.
+ * @return The value, or {@link Optional#empty()} if the section or key does not exist.
+ * @throws ParseException If value could not be parsed.
+ */
+ public Optional<OList> asList(Parser parser) throws ParseException {
+ return ofNullable(toList(parser));
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // Metadata retrievers
+ //-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Returns the name of this entry.
+ *
+ * @return The name of this entry.
+ */
+ public String getKey() {
+ return configEntry.getKey();
+ }
+
+ /**
+ * Returns the raw value of this entry.
+ *
+ * @return The raw value of this entry.
+ */
+ public String getValue() {
+ return configEntry.getValue();
+ }
+
+ /**
+ * Returns the same-line comment of this entry.
+ *
+ * @return The same-line comment of this entry.
+ */
+ public String getComment() {
+ return configEntry.getComment();
+ }
+
+ /**
+ * Returns the pre-lines of this entry.
+ *
+ * @return The pre-lines of this entry as an unmodifiable list.
+ */
+ public List<String> getPreLines() {
+ return configEntry.getPreLines();
+ }
+
+ /**
+ * Returns whether this entry has the specified modifier.
+ *
+ * @param m The modifier character.
+ * @return <jk>true</jk> if this entry is encoded.
+ */
+ public boolean hasModifier(char m) {
+ return configEntry.hasModifier(m);
+ }
+
+ /**
+ * Returns the modifiers for this entry.
+ *
+ * @return The modifiers for this entry, or an empty string if it has no modifiers.
+ */
+ public String getModifiers() {
+ return configEntry.getModifiers();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // Helper methods
+ //-----------------------------------------------------------------------------------------------------------------
+
+ private boolean isEmpty() {
+ return StringUtils.isEmpty(value);
+ }
+
+ private boolean isNull() {
+ return value == null;
+ }
+
+ private boolean isArray(Type t) {
+ if (! (t instanceof Class))
+ return false;
+ Class<?> c = (Class<?>)t;
+ return (c.isArray());
+ }
+
+ private boolean isSimpleType(Type t) {
+ if (! (t instanceof Class))
+ return false;
+ Class<?> c = (Class<?>)t;
+ return (c == String.class || c.isPrimitive() || c.isAssignableFrom(Number.class) || c == Boolean.class || c.isEnum());
+ }
+}
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/ConfigEntry.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/ConfigEntry.java
index 8b9faf3..89de958 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/ConfigEntry.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/ConfigEntry.java
@@ -81,6 +81,15 @@ public class ConfigEntry {
}
/**
+ * Returns the name of this entry.
+ *
+ * @return The name of this entry.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
* Returns the raw value of this entry.
*
* @return The raw value of this entry.
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/package-info.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/package-info.java
deleted file mode 100755
index e04991d..0000000
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/internal/package-info.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
-// * to you 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. *
-// ***************************************************************************************************************************
-
-/**
- * Internal Utilities
- */
-package org.apache.juneau.config.internal;
-
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/vars/ConfigVar.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/vars/ConfigVar.java
index 4bc6e4d..1595003 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/vars/ConfigVar.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/vars/ConfigVar.java
@@ -20,7 +20,7 @@ import org.apache.juneau.svl.*;
*
* <p>
* The format for this var is <js>"$C{key[,defaultValue]}"</js>.
- * See {@link Config#getString(String)} for the format of the key.
+ * See {@link Config#get(String)} for the format of the key.
*
* <p>
* This variable resolver requires that a {@link Config} bean be available in the resolver session bean factory.
@@ -65,7 +65,7 @@ public class ConfigVar extends DefaultingVar {
@Override /* Var */
public String resolve(VarResolverSession session, String key) {
- return session.getBean(Config.class).get().getString(key);
+ return session.getBean(Config.class).get().get(key).orElse(null);
}
@Override /* Var */
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 1e7831a..30183d9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -15,6 +15,7 @@ package org.apache.juneau.internal;
import static org.apache.juneau.assertions.Assertions.*;
import static org.apache.juneau.internal.ThrowableUtils.*;
import static org.apache.juneau.internal.IOUtils.*;
+
import java.io.*;
import java.lang.reflect.*;
import java.math.*;
@@ -2279,6 +2280,9 @@ public final class StringUtils {
* <li><js>"K"</js> - x 1024
* <li><js>"M"</js> - x 1024*1024
* <li><js>"G"</js> - x 1024*1024*1024
+ * <li><js>"k"</js> - x 1000
+ * <li><js>"m"</js> - x 1000*1000
+ * <li><js>"g"</js> - x 1000*1000*1000
* </ul>
*
* @param s The string to parse.
@@ -2286,18 +2290,21 @@ public final class StringUtils {
*/
public static int parseIntWithSuffix(String s) {
assertArgNotNull("s", s);
- int m = 1;
- if (s.endsWith("G")) {
- m = 1024*1024*1024;
- s = s.substring(0, s.length()-1).trim();
- } else if (s.endsWith("M")) {
- m = 1024*1024;
- s = s.substring(0, s.length()-1).trim();
- } else if (s.endsWith("K")) {
- m = 1024;
- s = s.substring(0, s.length()-1).trim();
- }
- return Integer.decode(s) * m;
+ int m = multiplier(s);
+ if (m == 1)
+ return Integer.decode(s);
+ return Integer.decode(s.substring(0, s.length()-1).trim()) * m;
+ }
+
+ private static int multiplier(String s) {
+ char c = s.length() == 0 ? null : s.charAt(s.length()-1);
+ if (c == 'G') return 1024*1024*1024;
+ if (c == 'M') return 1024*1024;
+ if (c == 'K') return 1024;
+ if (c == 'g') return 1000*1000*1000;
+ if (c == 'm') return 1000*1000;
+ if (c == 'k') return 1000;
+ return 1;
}
/**
@@ -2309,6 +2316,13 @@ public final class StringUtils {
* <li><js>"K"</js> - x 1024
* <li><js>"M"</js> - x 1024*1024
* <li><js>"G"</js> - x 1024*1024*1024
+ * <li><js>"T"</js> - x 1024*1024*1024*1024
+ * <li><js>"P"</js> - x 1024*1024*1024*1024*1024
+ * <li><js>"k"</js> - x 1000
+ * <li><js>"m"</js> - x 1000*1000
+ * <li><js>"g"</js> - x 1000*1000*1000
+ * <li><js>"t"</js> - x 1000*1000*1000*1000
+ * <li><js>"p"</js> - x 1000*1000*1000*1000*1000
* </ul>
*
* @param s The string to parse.
@@ -2316,18 +2330,25 @@ public final class StringUtils {
*/
public static long parseLongWithSuffix(String s) {
assertArgNotNull("s", s);
- int m = 1;
- if (s.endsWith("G")) {
- m = 1024*1024*1024;
- s = s.substring(0, s.length()-1).trim();
- } else if (s.endsWith("M")) {
- m = 1024*1024;
- s = s.substring(0, s.length()-1).trim();
- } else if (s.endsWith("K")) {
- m = 1024;
- s = s.substring(0, s.length()-1).trim();
- }
- return Long.decode(s) * m;
+ long m = multiplier2(s);
+ if (m == 1)
+ return Long.decode(s);
+ return Long.decode(s.substring(0, s.length()-1).trim()) * m;
+ }
+
+ private static long multiplier2(String s) {
+ char c = s.length() == 0 ? null : s.charAt(s.length()-1);
+ if (c == 'P') return 1024*1024*1024*1024*1024;
+ if (c == 'T') return 1024*1024*1024*1024;
+ if (c == 'G') return 1024*1024*1024;
+ if (c == 'M') return 1024*1024;
+ if (c == 'K') return 1024;
+ if (c == 'p') return 1000*1000*1000*1000*1000;
+ if (c == 't') return 1000*1000*1000*1000;
+ if (c == 'g') return 1000*1000*1000;
+ if (c == 'm') return 1000*1000;
+ if (c == 'k') return 1000;
+ return 1;
}
/**
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/05.jrs.Marshalling.html b/juneau-doc/docs/Topics/06.juneau-rest-server/05.jrs.Marshalling.html
index 4354651..ec056ef 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/05.jrs.Marshalling.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/05.jrs.Marshalling.html
@@ -106,6 +106,31 @@
| }
</p>
<p>
+ Swaps are associated serializers and parsers registered on a REST resource via the {@link oaj.annotation.BeanConfig} annotation
+ on either the class or method level:
+ </p>
+ <p class='bcode w800'>
+ | <jc>// Servlet with transforms applied</jc>
+ | <ja>@Rest</ja>(
+ | ...
+ | )
+ | <ja>@BeanConfig</ja>(
+ | swaps={
+ | <jc>// Calendars should be serialized/parsed as ISO8601 date-time strings</jc>
+ | TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
+ |
+ | <jc>// Byte arrays should be serialized/parsed as BASE64-encoded strings</jc>
+ | ByteArraySwap.Base64.<jk>class</jk>
+ | },
+ | beanFilters={
+ | <jc>// Subclasses of MyInterface will be treated as MyInterface objects.</jc>
+ | <jc>// Bean properties not defined on that interface will be ignored.</jc>
+ | MyInterface.<jk>class</jk>
+ | }
+ | )
+ | <jk>public</jk> MyResource <jk>extends</jk> BasicRestServlet {...}
+ </p>
+ <p>
Config annotations are defined for all serializers and parsers:
</p>
<ul class='javatreec'>
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.Guards.html b/juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Guards.html
similarity index 74%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.Guards.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Guards.html
index 3aae066..c84865e 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.Guards.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Guards.html
@@ -13,20 +13,24 @@
***************************************************************************************************************************/
-->
-{title:'Guards', flags:'todo'}
+{title:'Guards', updated:'9.0.0'}
<div class='topic'>
<p>
- Guards are classes that control access to REST classes and methods.
+ Guards control access to REST classes and methods.
+ When guards are associated at the class-level, it's equivalent to associating guards on all Java methods on
+ the servlet.
+ If multiple guards are present, ALL guards must pass. (Note that this is different in behavior to {@doc jrs.Matchers Matchers}
+ which require only one matcher to pass.)
</p>
<p>
Guards are associated with resource classes and methods via the following:
</p>
- <ul class='javatree'>
+ <ul class='javatreec'>
<li class='ja'>{@link oajr.annotation.Rest#guards() Rest(guards)}
<li class='ja'>{@link oajr.annotation.RestOp#guards() RestOp(guards)}
- <li class='jm'>{@del oajr.RestContext.Builder#guards(Class...)}
</ul>
+ <h5 class='figure'>Example:</h5>
<p class='bcode w800'>
| <jc>// Define a guard that only lets Billy make a request</jc>
| <jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
@@ -51,7 +55,7 @@
</p>
<p class='bcode w800'>
| <jc>// DELETE method</jc>
- | <ja>@RestDDelete</ja>(guards={AdminGuard.<jk>class</jk>})
+ | <ja>@RestDelete</ja>(guards={AdminGuard.<jk>class</jk>})
| <jk>public void</jk> doDelete(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {...}
</p>
<p class='bcode w800'>
@@ -65,7 +69,7 @@
</p>
<p>
A guard failure results in an <l>HTTP 401 Unauthorized</l> response.
- However, this can be configured by overriding the
+ However, this can be configured by overriding
{@link oajr.guard.RestGuard#guard(RestRequest,RestResponse)} and processing the response
yourself.
</p>
@@ -73,19 +77,29 @@
| <jk>public class</jk> AdminGuard <jk>extends</jk> RestGuard {
|
| <ja>@Override</ja> <jc>/* RestGuard */</jc>
- | <jk>public boolean</jk> guard(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> RestException {
+ | <jk>public boolean</jk> guard(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> BasicHttpException {
| <jk>if</jk> (! isOkay(req))
- | <jk>throw new</jk> RestException(<jsf>SC_FORBIDDEN</jsf>, <js>"Access denied!!!"</js>);
+ | <jk>throw new</jk> Forbidden(<js>"Access denied!!!"</js>);
| <jk>return true</jk>;
| }
| }
</p>
<p>
- When guards are associated at the class-level, it's equivalent to associating guards on all Java methods on
- the servlet.
- If multiple guards are present, ALL guards must pass.
+ A simplified format is available for matching based on the user role on the request using the following:
</p>
- <ul class='seealso'>
- <li class='jf'>{@del oajr.RestContext#REST_guards}
+
+ <ul class='javatreec'>
+ <li class='ja'>{@link oajr.annotation.Rest#roleGuard() Rest(roleGuard)}
+ <li class='ja'>{@link oajr.annotation.RestOp#roleGuard() RestOp(roleGuard)}
</ul>
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ | <ja>@Rest</ja>(
+ | path=<js>"/foo"</js>,
+ | roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js>
+ | )
+ | <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
+ | ...
+ | }
+ </p>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Transforms.html b/juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Transforms.html
deleted file mode 100644
index 56ce1f8..0000000
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/07.jrs.Transforms.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!--
-/***************************************************************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
- * to you 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.
- ***************************************************************************************************************************/
- -->
-
-{title:'Transforms', updated:'8.1.0', flags:'todo'}
-
-<div class='topic'>
- <p>
- The Juneau serializers and parsers can be configured on how to handle POJOs through the use of Transforms.
- (See {@doc jm.Swaps Swaps})
- </p>
- <p>
- Transforms are associated serializers and parsers registered on a REST resource via the following:
- </p>
- <ul class='javatree'>
- <li class='ja'>{@del BeanConfig#beanFilters() BeanConfig(beanFilters)} - On class or methods.
- <li class='ja'>{@link oaj.annotation.BeanConfig#swaps() BeanConfig(swaps)} - On class or methods.
- <li class='jm'>{@del RestContext.Builder#beanFilters(Object...)}
- <li class='jm'>{@del oajr.RestContext.Builder#swaps(Class...)}
- </ul>
- <p class='bcode w800'>
- | <jc>// Servlet with transforms applied</jc>
- | <ja>@Rest</ja>(
- | ...
- | )
- | <ja>@BeanConfig</ja>(
- | swaps={
- | <jc>// Calendars should be serialized/parsed as ISO8601 date-time strings</jc>
- | TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
- |
- | <jc>// Byte arrays should be serialized/parsed as BASE64-encoded strings</jc>
- | ByteArraySwap.Base64.<jk>class</jk>
- | },
- | beanFilters={
- | <jc>// Subclasses of MyInterface will be treated as MyInterface objects.</jc>
- | <jc>// Bean properties not defined on that interface will be ignored.</jc>
- | MyInterface.<jk>class</jk>
- | }
- | )
- | <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {...}
- </p>
- <p>
- The programmatic equivalent to this is:
- </p>
- <p class='bcode w800'>
- | <jc>// Servlet with properties applied</jc>
- | <ja>@Rest</ja>(...)
- | <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {
- |
- | <jk>public</jk> MyRestServlet(RestContext.Builder builder) {
- |
- | builder
- | .swaps(
- | TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
- | ByteArraySwap.Base64.<jk>class</jk>
- | )
- | .beanFilters(MyInterface.<jk>class</jk>);
- | }
- | }
- </p>
-</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.Converters.html b/juneau-doc/docs/Topics/06.juneau-rest-server/08.jrs.Converters.html
similarity index 52%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.Converters.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/08.jrs.Converters.html
index 26d3f78..ef28972 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.Converters.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/08.jrs.Converters.html
@@ -13,32 +13,21 @@
***************************************************************************************************************************/
-->
-{title:'Converters', flags:'todo'}
+{title:'Converters', updated:'9.0.0'}
<div class='topic'>
<p>
- Converters can be thought of as "post-processors" for POJOs before they get passed to the serializers.
+ Converters can be thought of as "post-processors" for response POJOs before they get passed to the serializer.
</p>
<p>
Converters are associated with resource classes and methods via the following:
</p>
- <ul class='javatree'>
+ <ul class='javatreec'>
<li class='ja'>{@link oajr.annotation.Rest#converters() Rest(converters)}
<li class='ja'>{@link oajr.annotation.RestOp#converters() RestOp(converters)}
- <li class='jm'>{@del oajr.RestContext.Builder#converters(Class...)}
</ul>
<h5 class='figure'>Example:</h5>
<p class='bcode w800'>
- | <jc>// Associate the Traversable converter to all Java REST methods in this servlet</jc>
- | <ja>@Rest</ja>(converters=Traversable.<jk>class</jk>)
- | <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {
- | ...
- | }
- </p>
- <p>
- They can also be defined at the method level:
- </p>
- <p class='bcode w800'>
| <jc>// GET person request handler.</jc>
| <jc>// Traversable conversion enabled to allow nodes in returned POJO tree to be addressed.</jc>
| <jc>// Queryable conversion enabled to allow returned POJO to be searched/viewed/sorted.</jc>
@@ -51,51 +40,12 @@
| }
</p>
<p>
- The following converter is used to provide support for addressing child nodes in a POJO tree with URL path
- remainders.
- In this code, the 3rd parameter is the object that was returned by the Java method.
- The converter uses the {@link oaj.utils.PojoRest} wrapper class to address nodes in the
- tree.
- </p>
- <p class='bcode w800'>
- | <jd>/**
- | * Converter for enablement of PojoRest support on response objects returned by a @RestOp method.
- | * When enabled, objects in a POJO tree returned by the REST method can be addressed through additional URL path information.
- | */</jd>
- | <jk>public class</jk> Traversable <jk>implements</jk> RestConverter {
- |
- | <ja>@Override</ja> <jc>/* RestConverter */</jc>
- | <jk>public</jk> Object convert(RestRequest <jv>req</jv>, Object <jv>o</jv>) <jk>throws</jk> RestException {
- | <jk>if</jk> (<jv>o</jv> == <jk>null</jk>)
- | <jk>return null</jk>;
- |
- | String <jv>pathRemainder</jv> = <jv>req</jv>.getPathMatch().getRemainder();
- |
- | <jk>if</jk> (<jv>pathRemainder</jv> != <jk>null</jk>) {
- | <jk>try</jk> {
- |
- | <jc>// Use the PojoRest class to traverse our POJO model.</jc>
- | PojoRest <jv>p</jv> = <jk>new</jk> PojoRest(<jv>o</jv>);
- | <jv>o</jv> = <jv>p</jv>.get(<jv>pathRemainder</jv>);
- |
- | } <jk>catch</jk> (PojoRestException <jv>e</jv>) {
- | <jk>throw new</jk> RestException(<jv>e</jv>.getStatus(), <jv>e</jv>);
- | } <jk>catch</jk> (Exception <jv>e</jv>) {
- | <jk>throw new</jk> RestException(HttpServletResponse.<jsf>SC_INTERNAL_SERVER_ERROR</jsf>, <jv>e</jv>);
- | }
- | }
- |
- | <jk>return</jk> <jv>o</jv>;
- | }
- | }
- </p>
- <p>
Juneau defines the following converters out-of-the-box:
</p>
<ul class='javatree'>
<li class='jic'>
- {@link oajr.RestConverter}
- <ul>
+ {@link oajr.converter.RestConverter}
+ <ul class='spaced-list'>
<li class='jc'>
{@link oajr.converter.Queryable}
<br>Provides query parameters that can be used to transform the response (i.e. search/view/sort the
@@ -110,8 +60,4 @@
serialized as the response.
</ul>
</ul>
-
- <ul class='seealso'>
- <li class='jf'>{@del oajr.RestContext#REST_converters}
- </ul>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/12.jrs.Messages.html b/juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.LocalizedMessages.html
similarity index 92%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/12.jrs.Messages.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.LocalizedMessages.html
index 42c1aab..a14f08e 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/12.jrs.Messages.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/09.jrs.LocalizedMessages.html
@@ -13,7 +13,7 @@
***************************************************************************************************************************/
-->
-{title:'Messages', updated:'8.2.0', flags:'todo'}
+{title:'Localized Messages', updated:'8.2.0,9.0.0'}
<div class='topic'>
<p>
@@ -37,15 +37,14 @@
</ul>
<p>
- This annotation is used to provide request-localized (based on <c>Accept-Language</c>) messages for the following methods:
+ This annotation is used to provide request-localized (based on <c>Accept-Language</c>) messages for the following method:
</p>
<ul class='javatree'>
<li class='jm'>{@link oajr.RestRequest#getMessage(String, Object...)}
- <li class='jm'>{@link oajr.RestContext#getMessages() RestContext.getMessages()}
</ul>
<p>
- Request-localized messages are also available by passing either of the following parameter types into your Java method:
+ Request-localized messages are also available by passing either of the following args into your Java method:
</p>
<ul class='javatree'>
<li class='jc'>{@link java.util.ResourceBundle} - Basic Java resource bundle.
@@ -102,9 +101,4 @@
Messages are automatically inherited from super classes. If a string cannot be found in the bundle of the current
class, it will be searched for up the class hierarchy.
</p>
-
- <ul class='seealso'>
- <li class='jc'>{@link oaj.cp.Messages}
- <li class='jf'>{@del oajr.RestContext#REST_messages}
- </ul>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/13.jrs.Encoders.html b/juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.Encoders.html
similarity index 94%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/13.jrs.Encoders.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.Encoders.html
index 4ec9a4f..9626ba1 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/13.jrs.Encoders.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.Encoders.html
@@ -13,7 +13,7 @@
***************************************************************************************************************************/
-->
-{title:'Encoders', flags:'todo'}
+{title:'Encoders', updated:'9.0.0'}
<div class='topic'>
<p>
@@ -44,8 +44,4 @@
{@link oaj.encoders.IdentityEncoder}
</ul>
</ul>
-
- <ul class='seealso'>
- <li class='jf'>{@del oajr.RestContext#REST_encoders}
- </ul>
</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.RoleGuards.html b/juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.RoleGuards.html
deleted file mode 100644
index 2cabe01..0000000
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/10.jrs.RoleGuards.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!--
-/***************************************************************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
- * to you 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.
- ***************************************************************************************************************************/
- -->
-
-{title:'Role guards', created:'8.1.0', flags:'todo'}
-
-<div class='topic'>
- <p>
- Specialized guards are provided for controlling access to servlet classes and methods based on user roles.
- These are controlled via annotations on the REST class and methods:
- </p>
- <ul class='javatree'>
- <li class='ja'>{@link oajr.annotation.Rest}
- <ul>
- <li class='jf'>{@link oajr.annotation.Rest#roleGuard() roleGuard()}
- <li class='jf'>{@link oajr.annotation.Rest#rolesDeclared() rolesDeclared()}
- </ul>
- <li class='ja'>{@link oajr.annotation.RestOp}
- <ul>
- <li class='jf'>{@link oajr.annotation.RestOp#roleGuard() roleGuard()}
- <li class='jf'>{@link oajr.annotation.RestOp#rolesDeclared() rolesDeclared()}
- </ul>
- </ul>
- <p>
- The <c>roleGuard()</c> annotation is an expression that defines whether a user with specified roles are allowed
- to access methods.
- </p>
- <h5 class='figure'>Example:</h5>
- <p class='bcode w800'>
- | <jc>// Only admin users or users with both read/write and special access
- | // can run any methods on this class.</jc>
- | <ja>@Rest</ja>(
- | path=<js>"/foo"</js>,
- | roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js>
- | )
- | <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
- | ...
- | }
- </p>
- <p>
- The syntax allows for any of the following:
- </p>
- <ul>
- <li><js>"foo"</js> - Single arguments.
- <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments.
- <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax.
- <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax.
- <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>.
- <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax.
- <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax.
- <li><js>"fo* || (*oo || bar)"</js> - Parenthesis.
- </ul>
-
- <p>
- If patterns are used, you must specify the list of declared roles using the <c>rolesDeclared()</c> annotations.
- This declares the list of all possible user roles and is needed because the servlet API does not provide this
- capability.
- </p>
-
- <h5 class='figure'>Example:</h5>
- <p class='bcode w800'>
- | <ja>@Rest</ja>(
- | rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>,
- | roleGuard=<js>"ROLE_ADMIN || (*WRITE* && *SPECIAL*)"</js>
- | )
- | <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
- | ...
- | }
- </p>
-</div>
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/15.jrs.ConfigurationFiles.html b/juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.ConfigurationFiles.html
similarity index 77%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/15.jrs.ConfigurationFiles.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.ConfigurationFiles.html
index 1f7937d..f90e938 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/15.jrs.ConfigurationFiles.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/11.jrs.ConfigurationFiles.html
@@ -13,12 +13,25 @@
***************************************************************************************************************************/
-->
-{title:'Configuration Files', flags:'todo'}
+{title:'Configuration Files', updated:'9.0.0'}
<div class='topic'>
<p>
The Server API provides methods for associating configuration files with REST servlets so that
- configuration properties can be defined in external files.
+ configuration properties can be defined in external files. It uses the following annotation:
+ </p>
+ <ul class='javatree'>
+ <li class='ja'>{@link oajr.annotation.Rest#config() Rest(config)}
+ </ul>
+
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ | <ja>@Rest</ja>(
+ | <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
+ | config=<js>"config_dir/myconfig.cfg"</js>,
+ | ...
+ | )
+ | <jk>public class</jk> MyResource {...}
</p>
<p>
In recap, the Configuration API provides support for INI-style configuration files with embedded string variables:
@@ -38,43 +51,46 @@
These properties are then accessible through the {@link oaj.config.Config} class.
</p>
<p class='bcode w800'>
- | Config c = Config.<jsm>create</jsm>(<js>"myconfig.cfg"</js>).build();
- | String path = c.getString(<js>"MyProperties/path"</js>);
- | File javaHome = c.getObject(<js>"MyProperties/javaHome"</js>, File.<jk>class</jk>);
- | String customMessage = c.getString(<js>"MyProperties/customMessage"</js>);
+ | <ja>@RestGet</ja>(<js>"/"</js>)
+ | <jk>public</jk> String sample(Config <jv>config</jv>) {
+ | String <jv>path</jv> = <jv>config</jv>.getString(<js>"MyProperties/path"</js>);
+ | File <jv>javaHome</jv> = <jv>config</jv>.getObject(<js>"MyProperties/javaHome"</js>, File.<jk>class</jk>);
+ | String <jv>customMessage</jv> = <jv>config</jv>.getString(<js>"MyProperties/customMessage"</js>);
+ | ...
+ | }
</p>
<p>
- Configuration files are associated with REST resources through the following:
+ The annotation itself can contain string variables.
+ For example, the Microservice API {@link oajr.BasicRestServlet} class defines the
+ location of the config file as a system property <l>"juneau.configFile"</l>:
</p>
- <ul class='javatree'>
- <li class='ja'>{@link oajr.annotation.Rest#config() Rest(config)}
- </ul>
-
- <h5 class='figure'>Example:</h5>
<p class='bcode w800'>
| <ja>@Rest</ja>(
- | <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
- | config=<js>"config_dir/myconfig.cfg"</js>,
+ | <jc>// Config file location is defined as a system property</jc>
+ | config=<js>"$S{juneau.configFile}"</js>,
| ...
| )
| <jk>public class</jk> MyResource {...}
</p>
<p>
- The annotation itself can contain string variables.
- For example, the Microservice API {@link oajr.BasicRestServlet} class defines the
- location of the config file as a system property <l>"juneau.configFile"</l>:
+ Spring Boot applications typically define an <c>application.properties</c> file. You can reuse it
+ as a config file like so:
</p>
<p class='bcode w800'>
| <ja>@Rest</ja>(
- | <jc>// Config file location is defined as a system property</jc>
- | config=<js>"$S{juneau.configFile}"</js>,
+ | config=<js>"application.properties"</js>,
| ...
| )
| <jk>public class</jk> MyResource {...}
</p>
<p>
- Once a config file has been associated with a REST resource, it can be accessed through the
- {@link oajr.RestContext.Builder#getConfig()} method.
+ Note that properties files are a subset of functionality of INI files (they're basically just INI files with a single default section).
+ It's therefore possible to use INI-style syntax such as sections in your <c>application.properties</c> file.
+ </p>
+ <p>
+ Once a config file has been associated with a REST resource, it can be accessed through one of the following:
+ {@link oajr.RestContext.Builder#getConfig()} method. It can also be access by passing in a {@link oaj.config.Config} bean to any of your
+ REST OP methods.
</p>
<p>
A common usage is to use this method to initialize fields in your servlet.
@@ -85,7 +101,7 @@
| config=<js>"config_dir/myconfig.cfg"</js>,
| ...
| )
- | <jk>public class</jk> MyResource {
+ | <jk>public class</jk> MyResource {
| <jk>private final</jk> String <jf>path</jf>;
| <jk>private final</jk> File <jf>javaHome</jf>;
|
@@ -99,12 +115,10 @@
Another common usage is to refer to config properties through <ck>$C</ck> variables in your annotations:
</p>
<p class='bcode w800'>
- | <ja>@Rest</ja>(
- | <jc>// Get stylesheet from myconfig.cfg, but default to devops.css if it's not specified</jc>
- | htmldoc=<ja>@HtmlDoc</ja>(
- | stylesheet=<js>"$C{MyServlet/stylesheet,servlet:/styles/devops.css}"</js>,
- | )
- | ...
+ | <ja>@Rest</ja>
+ | <jc>// Get stylesheet from myconfig.cfg, but default to devops.css if it's not specified</jc>
+ | <ja>@HtmlDoc</ja>(
+ | stylesheet=<js>"$C{MyServlet/stylesheet,servlet:/styles/devops.css}"</js>,
| )
| <jk>public class</jk> MyResource {...}
</p>
@@ -134,8 +148,8 @@
| * Specify the GET parameter "?person=X" for a specialized message!
| */</jd>
| <ja>@RestGet</ja>(<js>"/"</js>)
- | <jk>public</jk> String sayHello(RestRequest <jv>req</jv>) {
- | <jk>return</jk> <jv>req</jv>.getConfig().getString(<js>"HelloWorldResource/message"</js>);
+ | <jk>public</jk> String sayHello(Config <jv>config</jv>) {
+ | <jk>return</jk> <jv>config</jv>.getString(<js>"HelloWorldResource/message"</js>);
| }
| }
</p>
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/14.jrs.SvlVariables.html b/juneau-doc/docs/Topics/06.juneau-rest-server/12.jrs.SvlVariables.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/14.jrs.SvlVariables.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/12.jrs.SvlVariables.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.StaticFiles.html b/juneau-doc/docs/Topics/06.juneau-rest-server/13.jrs.StaticFiles.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.StaticFiles.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/13.jrs.StaticFiles.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/17.jrs.ClientVersioning.html b/juneau-doc/docs/Topics/06.juneau-rest-server/14.jrs.ClientVersioning.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/17.jrs.ClientVersioning.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/14.jrs.ClientVersioning.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.InfoProvider.html b/juneau-doc/docs/Topics/06.juneau-rest-server/15.jrs.InfoProvider.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.InfoProvider.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/15.jrs.InfoProvider.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/01.jrs.BasicRestServletSwagger.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/01.jrs.BasicRestServletSwagger.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/01.jrs.BasicRestServletSwagger.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/01.jrs.BasicRestServletSwagger.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/02.jrs.BasicSwaggerInfo.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/02.jrs.BasicSwaggerInfo.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/02.jrs.BasicSwaggerInfo.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/02.jrs.BasicSwaggerInfo.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/03.jrs.SwaggerTags.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/03.jrs.SwaggerTags.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/03.jrs.SwaggerTags.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/03.jrs.SwaggerTags.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/04.jrs.SwaggerOperations.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/04.jrs.SwaggerOperations.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/04.jrs.SwaggerOperations.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/04.jrs.SwaggerOperations.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/05.jrs.SwaggerParameters.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/05.jrs.SwaggerParameters.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/05.jrs.SwaggerParameters.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/05.jrs.SwaggerParameters.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/06.jrs.SwaggerParameterExamples.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/06.jrs.SwaggerParameterExamples.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/06.jrs.SwaggerParameterExamples.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/06.jrs.SwaggerParameterExamples.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/07.jrs.SwaggerResponses.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/07.jrs.SwaggerResponses.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/07.jrs.SwaggerResponses.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/07.jrs.SwaggerResponses.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/08.jrs.SwaggerResponseExamples.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/08.jrs.SwaggerResponseExamples.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/08.jrs.SwaggerResponseExamples.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/08.jrs.SwaggerResponseExamples.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/09.jrs.SwaggerModels.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/09.jrs.SwaggerModels.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/09.jrs.SwaggerModels.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/09.jrs.SwaggerModels.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/10.jrs.SwaggerStylesheet.html b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/10.jrs.SwaggerStylesheet.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/10.jrs.SwaggerStylesheet.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/10.jrs.SwaggerStylesheet.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.1.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.1.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.1.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.1.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.2.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.2.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.2.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.2.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.3.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.3.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Models.3.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Models.3.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.1.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.1.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.1.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.1.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.2.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.2.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.2.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.2.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.3.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.3.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Operations.3.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Operations.3.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.1.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.1.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.1.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.1.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.2.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.2.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.2.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.2.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.3.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.3.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.3.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.3.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.4.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.4.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.Parameters.4.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.Parameters.4.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.1.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.1.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.1.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.1.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.2.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.2.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.2.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.2.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.3.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.3.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.3.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.3.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.4.png b/juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.4.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.4.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/16.jrs.Swagger/doc-files/jrs.Swagger.ResponseExamples.4.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/20.jrs.ExecutionStatistics.html b/juneau-doc/docs/Topics/06.juneau-rest-server/17.jrs.ExecutionStatistics.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/20.jrs.ExecutionStatistics.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/17.jrs.ExecutionStatistics.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/01.jrs.HtmlUIvsDI.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/01.jrs.HtmlUIvsDI.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/01.jrs.HtmlUIvsDI.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/01.jrs.HtmlUIvsDI.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/02.jrs.HtmlWidgets.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/02.jrs.HtmlWidgets.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/02.jrs.HtmlWidgets.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/02.jrs.HtmlWidgets.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/03.jrs.HtmlPredefinedWidgets.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/03.jrs.HtmlPredefinedWidgets.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/03.jrs.HtmlPredefinedWidgets.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/03.jrs.HtmlPredefinedWidgets.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/04.jrs.HtmlUiCustomization.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/04.jrs.HtmlUiCustomization.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/04.jrs.HtmlUiCustomization.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/04.jrs.HtmlUiCustomization.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/05.jrs.HtmlStylesheets.html b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/05.jrs.HtmlStylesheets.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/05.jrs.HtmlStylesheets.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/05.jrs.HtmlStylesheets.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.1.png b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.1.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.1.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.1.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.2.png b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.2.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.2.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.2.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.3.png b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.3.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.3.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.3.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.4.png b/juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.4.png
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.4.png
rename to juneau-doc/docs/Topics/06.juneau-rest-server/18.jrs.HtmlDocAnnotation/doc-files/jrs.HtmlDocAnnotation.PredefinedWidgets.4.png
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/22.jrs.DefaultHeaders.html b/juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.DefaultHeaders.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/22.jrs.DefaultHeaders.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/19.jrs.DefaultHeaders.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/23.jrs.LoggingAndDebugging.html b/juneau-doc/docs/Topics/06.juneau-rest-server/20.jrs.LoggingAndDebugging.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/23.jrs.LoggingAndDebugging.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/20.jrs.LoggingAndDebugging.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/24.jrs.HttpStatusCodes.html b/juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HttpStatusCodes.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/24.jrs.HttpStatusCodes.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/21.jrs.HttpStatusCodes.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/25.jrs.OverloadingHttpMethods.html b/juneau-doc/docs/Topics/06.juneau-rest-server/22.jrs.OverloadingHttpMethods.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/25.jrs.OverloadingHttpMethods.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/22.jrs.OverloadingHttpMethods.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/26.jrs.BuiltInParameters.html b/juneau-doc/docs/Topics/06.juneau-rest-server/23.jrs.BuiltInParameters.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/26.jrs.BuiltInParameters.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/23.jrs.BuiltInParameters.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/27.jrs.CustomSerializersAndParsers.html b/juneau-doc/docs/Topics/06.juneau-rest-server/24.jrs.CustomSerializersAndParsers.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/27.jrs.CustomSerializersAndParsers.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/24.jrs.CustomSerializersAndParsers.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/28.jrs.UsingWithOsgi.html b/juneau-doc/docs/Topics/06.juneau-rest-server/25.jrs.UsingWithOsgi.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/28.jrs.UsingWithOsgi.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/25.jrs.UsingWithOsgi.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/29.jrs.Injection.html b/juneau-doc/docs/Topics/06.juneau-rest-server/26.jrs.Injection.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/29.jrs.Injection.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/26.jrs.Injection.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/30.jrs.OtherNotes.html b/juneau-doc/docs/Topics/06.juneau-rest-server/27.jrs.OtherNotes.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/30.jrs.OtherNotes.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/27.jrs.OtherNotes.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/31.jrs.RestContext.html b/juneau-doc/docs/Topics/06.juneau-rest-server/28.jrs.RestContext.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/31.jrs.RestContext.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/28.jrs.RestContext.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/32.jrs.RestRpc.html b/juneau-doc/docs/Topics/06.juneau-rest-server/29.jrs.RestRpc.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/32.jrs.RestRpc.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/29.jrs.RestRpc.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/33.jrs.CustomRestContextsAndBuilders.html b/juneau-doc/docs/Topics/06.juneau-rest-server/30.jrs.CustomRestContextsAndBuilders.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/33.jrs.CustomRestContextsAndBuilders.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/30.jrs.CustomRestContextsAndBuilders.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/36.jrs.ResponseProcessors.html b/juneau-doc/docs/Topics/06.juneau-rest-server/31.jrs.FluentAssertions.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/36.jrs.ResponseProcessors.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/31.jrs.FluentAssertions.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/37.jrs.UtilityBeans.html b/juneau-doc/docs/Topics/06.juneau-rest-server/32.jrs.Overview.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/37.jrs.UtilityBeans.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/32.jrs.Overview.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/34.jrs.FluentAssertions.html b/juneau-doc/docs/Topics/06.juneau-rest-server/33.jrs.ResponseProcessors.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/34.jrs.FluentAssertions.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/33.jrs.ResponseProcessors.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/35.jrs.Overview.html b/juneau-doc/docs/Topics/06.juneau-rest-server/34.jrs.UtilityBeans.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/35.jrs.Overview.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/34.jrs.UtilityBeans.html
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/08.jrs.HandlingUris.html b/juneau-doc/docs/Topics/06.juneau-rest-server/35.jrs.SerializingUris.html
similarity index 100%
rename from juneau-doc/docs/Topics/06.juneau-rest-server/08.jrs.HandlingUris.html
rename to juneau-doc/docs/Topics/06.juneau-rest-server/35.jrs.SerializingUris.html
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index a9ec7e0..8a0b850 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -375,15 +375,12 @@
</ol>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.Marshalling'>Marshalling</a><span class='update'>updated: <b>9.0.0</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.HandlingFormPosts'>Form Posts</a><span class='update'>updated: <b>9.0.0</b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.Transforms'>Transforms</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.HandlingUris'>URIs</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.Guards'>Guards</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.RoleGuards'>Role guards</a><span class='update'>created: 8.1.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.Converters'>Converters</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.Messages'>Messages</a><span class='update'>updated: 8.2.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.Encoders'>Encoders</a><span class='update'><b><red>todo</red></b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.Guards'>Guards</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.Converters'>Converters</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.LocalizedMessages'>Localized Messages</a><span class='update'>updated: 8.2.0,<b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.Encoders'>Encoders</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.ConfigurationFiles'>Configuration Files</a><span class='update'>updated: <b>9.0.0</b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.SvlVariables'>SVL Variables</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='#juneau-rest-server.jrs.ConfigurationFiles'>Configuration Files</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.StaticFiles'>Static files</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.ClientVersioning'>Client Versioning</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.InfoProvider'>RestInfoProvider</a><span class='update'><b><red>todo</red></b></span></p>
@@ -425,6 +422,7 @@
<li><p><a class='doclink' href='#juneau-rest-server.jrs.Overview'>Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.ResponseProcessors'>Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
<li><p><a class='doclink' href='#juneau-rest-server.jrs.UtilityBeans'>Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
+ <li><p><a class='doclink' href='#juneau-rest-server.jrs.SerializingUris'>URIs</a><span class='update'><b><red>todo</red></b></span></p>
</ol>
<li><p class='toc2'><a class='doclink' href='#juneau-rest-server-rdf'>juneau-rest-server-jaxrs</a></p>
<li><p class='toc2'><a class='doclink' href='#juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</a></p>
@@ -16896,6 +16894,31 @@
}
</p>
<p>
+ Swaps are associated serializers and parsers registered on a REST resource via the {@link org.apache.juneau.annotation.BeanConfig} annotation
+ on either the class or method level:
+ </p>
+ <p class='bcode w800'>
+ <jc>// Servlet with transforms applied</jc>
+ <ja>@Rest</ja>(
+ ...
+ )
+ <ja>@BeanConfig</ja>(
+ swaps={
+ <jc>// Calendars should be serialized/parsed as ISO8601 date-time strings</jc>
+ TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
+
+ <jc>// Byte arrays should be serialized/parsed as BASE64-encoded strings</jc>
+ ByteArraySwap.Base64.<jk>class</jk>
+ },
+ beanFilters={
+ <jc>// Subclasses of MyInterface will be treated as MyInterface objects.</jc>
+ <jc>// Bean properties not defined on that interface will be ignored.</jc>
+ MyInterface.<jk>class</jk>
+ }
+ )
+ <jk>public</jk> MyResource <jk>extends</jk> BasicRestServlet {...}
+ </p>
+ <p>
Config annotations are defined for all serializers and parsers:
</p>
<ul class='javatreec'>
@@ -17054,168 +17077,24 @@
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Transforms' id='juneau-rest-server.jrs.Transforms'>6.7 - Transforms</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.7 - juneau-rest-server.jrs.Transforms -->
-<div class='topic'>
- <p>
- The Juneau serializers and parsers can be configured on how to handle POJOs through the use of Transforms.
- (See {@doc jm.Swaps Swaps})
- </p>
- <p>
- Transforms are associated serializers and parsers registered on a REST resource via the following:
- </p>
- <ul class='javatree'>
- <li class='ja'>{@del BeanConfig#beanFilters() BeanConfig(beanFilters)} - On class or methods.
- <li class='ja'>{@link org.apache.juneau.annotation.BeanConfig#swaps() BeanConfig(swaps)} - On class or methods.
- <li class='jm'>{@del RestContext.Builder#beanFilters(Object...)}
- <li class='jm'>{@del org.apache.juneau.rest.RestContext.Builder#swaps(Class...)}
- </ul>
- <p class='bcode w800'>
- <jc>// Servlet with transforms applied</jc>
- <ja>@Rest</ja>(
- ...
- )
- <ja>@BeanConfig</ja>(
- swaps={
- <jc>// Calendars should be serialized/parsed as ISO8601 date-time strings</jc>
- TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
-
- <jc>// Byte arrays should be serialized/parsed as BASE64-encoded strings</jc>
- ByteArraySwap.Base64.<jk>class</jk>
- },
- beanFilters={
- <jc>// Subclasses of MyInterface will be treated as MyInterface objects.</jc>
- <jc>// Bean properties not defined on that interface will be ignored.</jc>
- MyInterface.<jk>class</jk>
- }
- )
- <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {...}
- </p>
- <p>
- The programmatic equivalent to this is:
- </p>
- <p class='bcode w800'>
- <jc>// Servlet with properties applied</jc>
- <ja>@Rest</ja>(...)
- <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {
-
- <jk>public</jk> MyRestServlet(RestContext.Builder builder) {
-
- builder
- .swaps(
- TemporalCalendarSwap.IsoInstant.<jk>class</jk>,
- ByteArraySwap.Base64.<jk>class</jk>
- )
- .beanFilters(MyInterface.<jk>class</jk>);
- }
- }
- </p>
-</div>
-</div><!-- END: 6.7 - juneau-rest-server.jrs.Transforms -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HandlingUris' id='juneau-rest-server.jrs.HandlingUris'>6.8 - URIs</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.8 - juneau-rest-server.jrs.HandlingUris -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Guards' id='juneau-rest-server.jrs.Guards'>6.7 - Guards</a><span class='update'>updated: <b>9.0.0</b></span></h3>
+<div class='topic'><!-- START: 6.7 - juneau-rest-server.jrs.Guards -->
<div class='topic'>
<p>
- As mention earlier {@doc jm.MarshallingUris here}, Juneau serializers have sophisticated support for transforming relative URIs to absolute form.
- </p>
- <p>
- The following example shows a REST method that returns a list of URIs of various forms:
- </p>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- uriAuthority=<js>"http://foo.com:123"</js>,
- uriContext=<js>"/myContext"</js>
- )
- <jk>public class</jk> MyResource {
-
- <ja>@RestGet</ja>
- <jk>public</jk> URI[] getURIs() {
- <jk>return new</jk> URI[] {
- URI.<jsm>create</jsm>(<js>"http://www.apache.org/f1a"</js>),
- URI.<jsm>create</jsm>(<js>"/f1b"</js>),
- URI.<jsm>create</jsm>(<js>"/f1c/x/y"</js>),
- URI.<jsm>create</jsm>(<js>"f1d"</js>),
- URI.<jsm>create</jsm>(<js>"f1e/x/y"</js>),
- URI.<jsm>create</jsm>(<js>""</js>),
- URI.<jsm>create</jsm>(<js>"context:/f2a/x"</js>),
- URI.<jsm>create</jsm>(<js>"context:/f2b"</js>),
- URI.<jsm>create</jsm>(<js>"context:/"</js>),
- URI.<jsm>create</jsm>(<js>"context:/.."</js>),
- URI.<jsm>create</jsm>(<js>"servlet:/f3a/x"</js>),
- URI.<jsm>create</jsm>(<js>"servlet:/f3b"</js>),
- URI.<jsm>create</jsm>(<js>"servlet:/"</js>),
- URI.<jsm>create</jsm>(<js>"servlet:/.."</js>),
- URI.<jsm>create</jsm>(<js>"request:/f4a/x"</js>),
- URI.<jsm>create</jsm>(<js>"request:/f4b"</js>),
- URI.<jsm>create</jsm>(<js>"request:/"</js>),
- URI.<jsm>create</jsm>(<js>"request:/.."</js>)
- };
- }
- }
- </p>
- <p>
- When requested as JSON, it produces the following result:
- </p>
- <p class='bcode w800'>
- {
- <jok>f1a</jok>:<jov>'http://www.apache.org/f1a'</jov>,
- <jok>f1b</jok>:<jov>'http://foo.com:123/f1b'</jov>,
- <jok>f1c</jok>:<jov>'http://foo.com:123/f1c/x/y'</jov>,
- <jok>f1d</jok>:<jov>'http://foo.com:123/myContext/myServlet/f1d'</jov>,
- <jok>f1e</jok>:<jov>'http://foo.com:123/myContext/myServlet/f1e/x/y'</jov>,
- <jok>f1f</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>,
- <jok>f2a</jok>:<jov>'http://foo.com:123/myContext/f2a/x'</jov>,
- <jok>f2b</jok>:<jov>'http://foo.com:123/myContext/f2b'</jov>,
- <jok>f2c</jok>:<jov>'http://foo.com:123/myContext'</jov>,
- <jok>f2d</jok>:<jov>'http://foo.com:123'</jov>,
- <jok>f3a</jok>:<jov>'http://foo.com:123/myContext/myServlet/f3a/x'</jov>,
- <jok>f3b</jok>:<jov>'http://foo.com:123/myContext/myServlet/f3b'</jov>,
- <jok>f3c</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>,
- <jok>f3d</jok>:<jov>'http://foo.com:123/myContext'</jov>,
- <jok>f4a</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath/f4a/x'</jov>,
- <jok>f4b</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath/f4b'</jov>,
- <jok>f4c</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath'</jov>,
- <jok>f4d</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>
- }
- </p>
- <p>
- URI resolution is controlled by the following settings:
- </p>
- <ul class='javatree'>
- <li class='jc'>{@link org.apache.juneau.rest.RestContext}
- <ul>
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriAuthority REST_uriAuthority}
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriContext REST_uriContext}
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriRelativity REST_uriRelativity}
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriResolution REST_uriResolution}
- </ul>
- </ul>
-
- <p>
- URIs are resolved by both regular and part serializers.
- </p>
-</div>
-</div><!-- END: 6.8 - juneau-rest-server.jrs.HandlingUris -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Guards' id='juneau-rest-server.jrs.Guards'>6.9 - Guards</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.9 - juneau-rest-server.jrs.Guards -->
-<div class='topic'>
- <p>
- Guards are classes that control access to REST classes and methods.
+ Guards control access to REST classes and methods.
+ When guards are associated at the class-level, it's equivalent to associating guards on all Java methods on
+ the servlet.
+ If multiple guards are present, ALL guards must pass. (Note that this is different in behavior to {@doc jrs.Matchers Matchers}
+ which require only one matcher to pass.)
</p>
<p>
Guards are associated with resource classes and methods via the following:
</p>
- <ul class='javatree'>
+ <ul class='javatreec'>
<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#guards() Rest(guards)}
<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#guards() RestOp(guards)}
- <li class='jm'>{@del org.apache.juneau.rest.RestContext.Builder#guards(Class...)}
</ul>
+ <h5 class='figure'>Example:</h5>
<p class='bcode w800'>
<jc>// Define a guard that only lets Billy make a request</jc>
<jk>public</jk> BillyGuard <jk>extends</jk> RestGuard {
@@ -17240,7 +17119,7 @@
</p>
<p class='bcode w800'>
<jc>// DELETE method</jc>
- <ja>@RestDDelete</ja>(guards={AdminGuard.<jk>class</jk>})
+ <ja>@RestDelete</ja>(guards={AdminGuard.<jk>class</jk>})
<jk>public void</jk> doDelete(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {...}
</p>
<p class='bcode w800'>
@@ -17254,7 +17133,7 @@
</p>
<p>
A guard failure results in an <l>HTTP 401 Unauthorized</l> response.
- However, this can be configured by overriding the
+ However, this can be configured by overriding
{@link org.apache.juneau.rest.guard.RestGuard#guard(RestRequest,RestResponse)} and processing the response
yourself.
</p>
@@ -17262,53 +17141,23 @@
<jk>public class</jk> AdminGuard <jk>extends</jk> RestGuard {
<ja>@Override</ja> <jc>/* RestGuard */</jc>
- <jk>public boolean</jk> guard(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> RestException {
+ <jk>public boolean</jk> guard(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> BasicHttpException {
<jk>if</jk> (! isOkay(req))
- <jk>throw new</jk> RestException(<jsf>SC_FORBIDDEN</jsf>, <js>"Access denied!!!"</js>);
+ <jk>throw new</jk> Forbidden(<js>"Access denied!!!"</js>);
<jk>return true</jk>;
}
}
</p>
<p>
- When guards are associated at the class-level, it's equivalent to associating guards on all Java methods on
- the servlet.
- If multiple guards are present, ALL guards must pass.
+ A simplified format is available for matching based on the user role on the request using the following:
</p>
- <ul class='seealso'>
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_guards}
- </ul>
-</div>
-</div><!-- END: 6.9 - juneau-rest-server.jrs.Guards -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.RoleGuards' id='juneau-rest-server.jrs.RoleGuards'>6.10 - Role guards</a><span class='update'>created: 8.1.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.10 - juneau-rest-server.jrs.RoleGuards -->
-<div class='topic'>
- <p>
- Specialized guards are provided for controlling access to servlet classes and methods based on user roles.
- These are controlled via annotations on the REST class and methods:
- </p>
- <ul class='javatree'>
- <li class='ja'>{@link org.apache.juneau.rest.annotation.Rest}
- <ul>
- <li class='jf'>{@link org.apache.juneau.rest.annotation.Rest#roleGuard() roleGuard()}
- <li class='jf'>{@link org.apache.juneau.rest.annotation.Rest#rolesDeclared() rolesDeclared()}
- </ul>
- <li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp}
- <ul>
- <li class='jf'>{@link org.apache.juneau.rest.annotation.RestOp#roleGuard() roleGuard()}
- <li class='jf'>{@link org.apache.juneau.rest.annotation.RestOp#rolesDeclared() rolesDeclared()}
- </ul>
+
+ <ul class='javatreec'>
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#roleGuard() Rest(roleGuard)}
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#roleGuard() RestOp(roleGuard)}
</ul>
- <p>
- The <c>roleGuard()</c> annotation is an expression that defines whether a user with specified roles are allowed
- to access methods.
- </p>
<h5 class='figure'>Example:</h5>
<p class='bcode w800'>
- <jc>// Only admin users or users with both read/write and special access
- // can run any methods on this class.</jc>
<ja>@Rest</ja>(
path=<js>"/foo"</js>,
roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js>
@@ -17317,67 +17166,26 @@
...
}
</p>
- <p>
- The syntax allows for any of the following:
- </p>
- <ul>
- <li><js>"foo"</js> - Single arguments.
- <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments.
- <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax.
- <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax.
- <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>.
- <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax.
- <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax.
- <li><js>"fo* || (*oo || bar)"</js> - Parenthesis.
- </ul>
-
- <p>
- If patterns are used, you must specify the list of declared roles using the <c>rolesDeclared()</c> annotations.
- This declares the list of all possible user roles and is needed because the servlet API does not provide this
- capability.
- </p>
-
- <h5 class='figure'>Example:</h5>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>,
- roleGuard=<js>"ROLE_ADMIN || (*WRITE* && *SPECIAL*)"</js>
- )
- <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
- ...
- }
- </p>
</div>
-</div><!-- END: 6.10 - juneau-rest-server.jrs.RoleGuards -->
+</div><!-- END: 6.7 - juneau-rest-server.jrs.Guards -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Converters' id='juneau-rest-server.jrs.Converters'>6.11 - Converters</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.11 - juneau-rest-server.jrs.Converters -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Converters' id='juneau-rest-server.jrs.Converters'>6.8 - Converters</a><span class='update'>updated: <b>9.0.0</b></span></h3>
+<div class='topic'><!-- START: 6.8 - juneau-rest-server.jrs.Converters -->
<div class='topic'>
<p>
- Converters can be thought of as "post-processors" for POJOs before they get passed to the serializers.
+ Converters can be thought of as "post-processors" for response POJOs before they get passed to the serializer.
</p>
<p>
Converters are associated with resource classes and methods via the following:
</p>
- <ul class='javatree'>
+ <ul class='javatreec'>
<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#converters() Rest(converters)}
<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#converters() RestOp(converters)}
- <li class='jm'>{@del org.apache.juneau.rest.RestContext.Builder#converters(Class...)}
</ul>
<h5 class='figure'>Example:</h5>
<p class='bcode w800'>
- <jc>// Associate the Traversable converter to all Java REST methods in this servlet</jc>
- <ja>@Rest</ja>(converters=Traversable.<jk>class</jk>)
- <jk>public</jk> MyRestServlet <jk>extends</jk> BasicRestServlet {
- ...
- }
- </p>
- <p>
- They can also be defined at the method level:
- </p>
- <p class='bcode w800'>
<jc>// GET person request handler.</jc>
<jc>// Traversable conversion enabled to allow nodes in returned POJO tree to be addressed.</jc>
<jc>// Queryable conversion enabled to allow returned POJO to be searched/viewed/sorted.</jc>
@@ -17390,51 +17198,12 @@
}
</p>
<p>
- The following converter is used to provide support for addressing child nodes in a POJO tree with URL path
- remainders.
- In this code, the 3rd parameter is the object that was returned by the Java method.
- The converter uses the {@link org.apache.juneau.utils.PojoRest} wrapper class to address nodes in the
- tree.
- </p>
- <p class='bcode w800'>
- <jd>/**
- * Converter for enablement of PojoRest support on response objects returned by a @RestOp method.
- * When enabled, objects in a POJO tree returned by the REST method can be addressed through additional URL path information.
- */</jd>
- <jk>public class</jk> Traversable <jk>implements</jk> RestConverter {
-
- <ja>@Override</ja> <jc>/* RestConverter */</jc>
- <jk>public</jk> Object convert(RestRequest <jv>req</jv>, Object <jv>o</jv>) <jk>throws</jk> RestException {
- <jk>if</jk> (<jv>o</jv> == <jk>null</jk>)
- <jk>return null</jk>;
-
- String <jv>pathRemainder</jv> = <jv>req</jv>.getPathMatch().getRemainder();
-
- <jk>if</jk> (<jv>pathRemainder</jv> != <jk>null</jk>) {
- <jk>try</jk> {
-
- <jc>// Use the PojoRest class to traverse our POJO model.</jc>
- PojoRest <jv>p</jv> = <jk>new</jk> PojoRest(<jv>o</jv>);
- <jv>o</jv> = <jv>p</jv>.get(<jv>pathRemainder</jv>);
-
- } <jk>catch</jk> (PojoRestException <jv>e</jv>) {
- <jk>throw new</jk> RestException(<jv>e</jv>.getStatus(), <jv>e</jv>);
- } <jk>catch</jk> (Exception <jv>e</jv>) {
- <jk>throw new</jk> RestException(HttpServletResponse.<jsf>SC_INTERNAL_SERVER_ERROR</jsf>, <jv>e</jv>);
- }
- }
-
- <jk>return</jk> <jv>o</jv>;
- }
- }
- </p>
- <p>
Juneau defines the following converters out-of-the-box:
</p>
<ul class='javatree'>
<li class='jic'>
- {@link org.apache.juneau.rest.RestConverter}
- <ul>
+ {@link org.apache.juneau.rest.converter.RestConverter}
+ <ul class='spaced-list'>
<li class='jc'>
{@link org.apache.juneau.rest.converter.Queryable}
<br>Provides query parameters that can be used to transform the response (i.e. search/view/sort the
@@ -17449,17 +17218,13 @@
serialized as the response.
</ul>
</ul>
-
- <ul class='seealso'>
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_converters}
- </ul>
</div>
-</div><!-- END: 6.11 - juneau-rest-server.jrs.Converters -->
+</div><!-- END: 6.8 - juneau-rest-server.jrs.Converters -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Messages' id='juneau-rest-server.jrs.Messages'>6.12 - Messages</a><span class='update'>updated: 8.2.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.12 - juneau-rest-server.jrs.Messages -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.LocalizedMessages' id='juneau-rest-server.jrs.LocalizedMessages'>6.9 - Localized Messages</a><span class='update'>updated: 8.2.0,<b>9.0.0</b></span></h3>
+<div class='topic'><!-- START: 6.9 - juneau-rest-server.jrs.LocalizedMessages -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.annotation.Rest#messages @Rest(messages)} annotation identifies the location of the resource bundle
@@ -17482,15 +17247,14 @@
</ul>
<p>
- This annotation is used to provide request-localized (based on <c>Accept-Language</c>) messages for the following methods:
+ This annotation is used to provide request-localized (based on <c>Accept-Language</c>) messages for the following method:
</p>
<ul class='javatree'>
<li class='jm'>{@link org.apache.juneau.rest.RestRequest#getMessage(String, Object...)}
- <li class='jm'>{@link org.apache.juneau.rest.RestContext#getMessages() RestContext.getMessages()}
</ul>
<p>
- Request-localized messages are also available by passing either of the following parameter types into your Java method:
+ Request-localized messages are also available by passing either of the following args into your Java method:
</p>
<ul class='javatree'>
<li class='jc'>{@link java.util.ResourceBundle} - Basic Java resource bundle.
@@ -17547,18 +17311,13 @@
Messages are automatically inherited from super classes. If a string cannot be found in the bundle of the current
class, it will be searched for up the class hierarchy.
</p>
-
- <ul class='seealso'>
- <li class='jc'>{@link org.apache.juneau.cp.Messages}
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_messages}
- </ul>
</div>
-</div><!-- END: 6.12 - juneau-rest-server.jrs.Messages -->
+</div><!-- END: 6.9 - juneau-rest-server.jrs.LocalizedMessages -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Encoders' id='juneau-rest-server.jrs.Encoders'>6.13 - Encoders</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.13 - juneau-rest-server.jrs.Encoders -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Encoders' id='juneau-rest-server.jrs.Encoders'>6.10 - Encoders</a><span class='update'>updated: <b>9.0.0</b></span></h3>
+<div class='topic'><!-- START: 6.10 - juneau-rest-server.jrs.Encoders -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.annotation.Rest#encoders @Rest(encoders)} annotation can
@@ -17578,27 +17337,209 @@
<p>
Juneau defines the following encoders out-of-the-box:
</p>
- <ul class='javatree'>
- <li class='jac'>
- {@link org.apache.juneau.encoders.Encoder}
- <ul>
- <li class='jc'>
- {@link org.apache.juneau.encoders.GzipEncoder}
- <li class='jc'>
- {@link org.apache.juneau.encoders.IdentityEncoder}
- </ul>
- </ul>
+ <ul class='javatree'>
+ <li class='jac'>
+ {@link org.apache.juneau.encoders.Encoder}
+ <ul>
+ <li class='jc'>
+ {@link org.apache.juneau.encoders.GzipEncoder}
+ <li class='jc'>
+ {@link org.apache.juneau.encoders.IdentityEncoder}
+ </ul>
+ </ul>
+</div>
+</div><!-- END: 6.10 - juneau-rest-server.jrs.Encoders -->
+
+<!-- ==================================================================================================== -->
+
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ConfigurationFiles' id='juneau-rest-server.jrs.ConfigurationFiles'>6.11 - Configuration Files</a><span class='update'>updated: <b>9.0.0</b></span></h3>
+<div class='topic'><!-- START: 6.11 - juneau-rest-server.jrs.ConfigurationFiles -->
+<div class='topic'>
+ <p>
+ The Server API provides methods for associating configuration files with REST servlets so that
+ configuration properties can be defined in external files. It uses the following annotation:
+ </p>
+ <ul class='javatree'>
+ <li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#config() Rest(config)}
+ </ul>
+
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>(
+ <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
+ config=<js>"config_dir/myconfig.cfg"</js>,
+ ...
+ )
+ <jk>public class</jk> MyResource {...}
+ </p>
+ <p>
+ In recap, the Configuration API provides support for INI-style configuration files with embedded string variables:
+ </p>
+
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ <cc>#--------------------------</cc>
+ <cc># Examples </cc>
+ <cc>#--------------------------</cc>
+ <cs>[MyProperties]</cs>
+ <ck>path</ck> = <cv>$E{PATH}</cv>
+ <ck>javaHome</ck> = <cv>$S{java.home}</cv>
+ <ck>customMessage</ck> = <cv>Java home is $C{MyProperties/javaHome} and the environment path is $C{MyProperties/path}.</cv>
+ </p>
+ <p>
+ These properties are then accessible through the {@link org.apache.juneau.config.Config} class.
+ </p>
+ <p class='bcode w800'>
+ <ja>@RestGet</ja>(<js>"/"</js>)
+ <jk>public</jk> String sample(Config <jv>config</jv>) {
+ String <jv>path</jv> = <jv>config</jv>.getString(<js>"MyProperties/path"</js>);
+ File <jv>javaHome</jv> = <jv>config</jv>.getObject(<js>"MyProperties/javaHome"</js>, File.<jk>class</jk>);
+ String <jv>customMessage</jv> = <jv>config</jv>.getString(<js>"MyProperties/customMessage"</js>);
+ ...
+ }
+ </p>
+ <p>
+ The annotation itself can contain string variables.
+ For example, the Microservice API {@link org.apache.juneau.rest.BasicRestServlet} class defines the
+ location of the config file as a system property <l>"juneau.configFile"</l>:
+ </p>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>(
+ <jc>// Config file location is defined as a system property</jc>
+ config=<js>"$S{juneau.configFile}"</js>,
+ ...
+ )
+ <jk>public class</jk> MyResource {...}
+ </p>
+ <p>
+ Spring Boot applications typically define an <c>application.properties</c> file. You can reuse it
+ as a config file like so:
+ </p>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>(
+ config=<js>"application.properties"</js>,
+ ...
+ )
+ <jk>public class</jk> MyResource {...}
+ </p>
+ <p>
+ Note that properties files are a subset of functionality of INI files (they're basically just INI files with a single default section).
+ It's therefore possible to use INI-style syntax such as sections in your <c>application.properties</c> file.
+ </p>
+ <p>
+ Once a config file has been associated with a REST resource, it can be accessed through one of the following:
+ {@link org.apache.juneau.rest.RestContext.Builder#getConfig()} method. It can also be access by passing in a {@link org.apache.juneau.config.Config} bean to any of your
+ REST OP methods.
+ </p>
+ <p>
+ A common usage is to use this method to initialize fields in your servlet.
+ </p>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>(
+ <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
+ config=<js>"config_dir/myconfig.cfg"</js>,
+ ...
+ )
+ <jk>public class</jk> MyResource {
+ <jk>private final</jk> String <jf>path</jf>;
+ <jk>private final</jk> File <jf>javaHome</jf>;
+
+ <jk>public</jk> MyResource(RestContext.Builder builder) {
+ Config c = builder.getConfig();
+ <jf>path</jf> = c.getString(<js>"MyProperties/path"</js>);
+ <jf>javaHome</jf> = c.getObject(File.<jk>class</jk>, <js>"MyProperties/javaHome"</js>);
+ }
+ </p>
+ <p>
+ Another common usage is to refer to config properties through <ck>$C</ck> variables in your annotations:
+ </p>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>
+ <jc>// Get stylesheet from myconfig.cfg, but default to devops.css if it's not specified</jc>
+ <ja>@HtmlDoc</ja>(
+ stylesheet=<js>"$C{MyServlet/stylesheet,servlet:/styles/devops.css}"</js>,
+ )
+ <jk>public class</jk> MyResource {...}
+ </p>
+ <p>
+ It's even possible to reference request-level variables in your config file if you use
+ {@link org.apache.juneau.rest.RestRequest#getConfig()} to access the config file:
+ </p>
+ <p class='bcode w800'>
+ <cc>#-------------------------------------</cc>
+ <cc># Contents of config_dir/myconfig.cfg </cc>
+ <cc>#-------------------------------------</cc>
+ <cs>[HelloWorldResource]</cs>
+ <ck>message</ck> = <cv>Hello $RQ{person}!</cv>
+ </p>
+ <p class='bcode w800'>
+ <jd>/**
+ * Sample REST resource that prints out a simple "Hello world!" message.
+ */</jd>
+ <ja>@Rest</ja>(
+ config=<js>"config_dir/myconfig.cfg"</js>,
+ ...
+ )
+ <jk>public class</jk> HelloWorldResource <jk>extends</jk> BasicRestServlet {
+
+ <jd>/**
+ * GET request handler.
+ * Specify the GET parameter "?person=X" for a specialized message!
+ */</jd>
+ <ja>@RestGet</ja>(<js>"/"</js>)
+ <jk>public</jk> String sayHello(Config <jv>config</jv>) {
+ <jk>return</jk> <jv>config</jv>.getString(<js>"HelloWorldResource/message"</js>);
+ }
+ }
+ </p>
+ <p>
+ You can even add resource bundles into the mix:
+ </p>
+ <p class='bcode w800'>
+ <cc>#-------------------------------------</cc>
+ <cc># Contents of config_dir/myconfig.cfg </cc>
+ <cc>#-------------------------------------</cc>
+ <cs>[HelloWorldResource]</cs>
+ <ck>message</ck> = <cv>$L{localizedMessage,$RQ{person}}</cv>
+ </p>
+ <p class='bcode w800'>
+ <cc>#-------------------------------------------</cc>
+ <cc># Contents of HelloWorldResource.properties </cc>
+ <cc>#-------------------------------------------</cc>
+ <ck>localizedMessage</ck> = <cv>Hello {0}!</cv>
+ </p>
+ <p class='bcode w800'>
+ <jd>/**
+ * Sample REST resource that prints out a simple "Hello world!" message.
+ */</jd>
+ <ja>@Rest</ja>(
+ messages=<js>"HelloWorldResources"</js>,
+ config=<js>"config_dir/myconfig.cfg"</js>,
+ ...
+ )
+ <jk>public class</jk> HelloWorldResource <jk>extends</jk> BasicRestServlet {
+
+ <jd>/**
+ * GET request handler.
+ * Specify the GET parameter "?person=X" for a specialized message!
+ */</jd>
+ <ja>@RestGet</ja>(<js>"/"</js>)
+ <jk>public</jk> String sayHello(RestRequest <jv>req</jv>) {
+ <jk>return</jk> <jv>req</jv>.getConfig().getString(<js>"HelloWorldResource/message"</js>);
+ }
+ }
+ </p>
<ul class='seealso'>
- <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_encoders}
+ <li>{@doc juneau-config}
</ul>
</div>
-</div><!-- END: 6.13 - juneau-rest-server.jrs.Encoders -->
+</div><!-- END: 6.11 - juneau-rest-server.jrs.ConfigurationFiles -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.SvlVariables' id='juneau-rest-server.jrs.SvlVariables'>6.14 - SVL Variables</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.14 - juneau-rest-server.jrs.SvlVariables -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.SvlVariables' id='juneau-rest-server.jrs.SvlVariables'>6.12 - SVL Variables</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.12 - juneau-rest-server.jrs.SvlVariables -->
<div class='topic'>
<p>
In the previous examples, there were several cases where embedded variables were contained within
@@ -17869,184 +17810,12 @@
</tr>
</table>
</div>
-</div><!-- END: 6.14 - juneau-rest-server.jrs.SvlVariables -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ConfigurationFiles' id='juneau-rest-server.jrs.ConfigurationFiles'>6.15 - Configuration Files</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.15 - juneau-rest-server.jrs.ConfigurationFiles -->
-<div class='topic'>
- <p>
- The Server API provides methods for associating configuration files with REST servlets so that
- configuration properties can be defined in external files.
- </p>
- <p>
- In recap, the Configuration API provides support for INI-style configuration files with embedded string variables:
- </p>
-
- <h5 class='figure'>Example:</h5>
- <p class='bcode w800'>
- <cc>#--------------------------</cc>
- <cc># Examples </cc>
- <cc>#--------------------------</cc>
- <cs>[MyProperties]</cs>
- <ck>path</ck> = <cv>$E{PATH}</cv>
- <ck>javaHome</ck> = <cv>$S{java.home}</cv>
- <ck>customMessage</ck> = <cv>Java home is $C{MyProperties/javaHome} and the environment path is $C{MyProperties/path}.</cv>
- </p>
- <p>
- These properties are then accessible through the {@link org.apache.juneau.config.Config} class.
- </p>
- <p class='bcode w800'>
- Config c = Config.<jsm>create</jsm>(<js>"myconfig.cfg"</js>).build();
- String path = c.getString(<js>"MyProperties/path"</js>);
- File javaHome = c.getObject(<js>"MyProperties/javaHome"</js>, File.<jk>class</jk>);
- String customMessage = c.getString(<js>"MyProperties/customMessage"</js>);
- </p>
- <p>
- Configuration files are associated with REST resources through the following:
- </p>
- <ul class='javatree'>
- <li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#config() Rest(config)}
- </ul>
-
- <h5 class='figure'>Example:</h5>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
- config=<js>"config_dir/myconfig.cfg"</js>,
- ...
- )
- <jk>public class</jk> MyResource {...}
- </p>
- <p>
- The annotation itself can contain string variables.
- For example, the Microservice API {@link org.apache.juneau.rest.BasicRestServlet} class defines the
- location of the config file as a system property <l>"juneau.configFile"</l>:
- </p>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- <jc>// Config file location is defined as a system property</jc>
- config=<js>"$S{juneau.configFile}"</js>,
- ...
- )
- <jk>public class</jk> MyResource {...}
- </p>
- <p>
- Once a config file has been associated with a REST resource, it can be accessed through the
- {@link org.apache.juneau.rest.RestContext.Builder#getConfig()} method.
- </p>
- <p>
- A common usage is to use this method to initialize fields in your servlet.
- </p>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- <jc>// Config file is located at ./config_dir/myconfig.cfg</jc>
- config=<js>"config_dir/myconfig.cfg"</js>,
- ...
- )
- <jk>public class</jk> MyResource {
- <jk>private final</jk> String <jf>path</jf>;
- <jk>private final</jk> File <jf>javaHome</jf>;
-
- <jk>public</jk> MyResource(RestContext.Builder builder) {
- Config c = builder.getConfig();
- <jf>path</jf> = c.getString(<js>"MyProperties/path"</js>);
- <jf>javaHome</jf> = c.getObject(File.<jk>class</jk>, <js>"MyProperties/javaHome"</js>);
- }
- </p>
- <p>
- Another common usage is to refer to config properties through <ck>$C</ck> variables in your annotations:
- </p>
- <p class='bcode w800'>
- <ja>@Rest</ja>(
- <jc>// Get stylesheet from myconfig.cfg, but default to devops.css if it's not specified</jc>
- htmldoc=<ja>@HtmlDoc</ja>(
- stylesheet=<js>"$C{MyServlet/stylesheet,servlet:/styles/devops.css}"</js>,
- )
- ...
- )
- <jk>public class</jk> MyResource {...}
- </p>
- <p>
- It's even possible to reference request-level variables in your config file if you use
- {@link org.apache.juneau.rest.RestRequest#getConfig()} to access the config file:
- </p>
- <p class='bcode w800'>
- <cc>#-------------------------------------</cc>
- <cc># Contents of config_dir/myconfig.cfg </cc>
- <cc>#-------------------------------------</cc>
- <cs>[HelloWorldResource]</cs>
- <ck>message</ck> = <cv>Hello $RQ{person}!</cv>
- </p>
- <p class='bcode w800'>
- <jd>/**
- * Sample REST resource that prints out a simple "Hello world!" message.
- */</jd>
- <ja>@Rest</ja>(
- config=<js>"config_dir/myconfig.cfg"</js>,
- ...
- )
- <jk>public class</jk> HelloWorldResource <jk>extends</jk> BasicRestServlet {
-
- <jd>/**
- * GET request handler.
- * Specify the GET parameter "?person=X" for a specialized message!
- */</jd>
- <ja>@RestGet</ja>(<js>"/"</js>)
- <jk>public</jk> String sayHello(RestRequest <jv>req</jv>) {
- <jk>return</jk> <jv>req</jv>.getConfig().getString(<js>"HelloWorldResource/message"</js>);
- }
- }
- </p>
- <p>
- You can even add resource bundles into the mix:
- </p>
- <p class='bcode w800'>
- <cc>#-------------------------------------</cc>
- <cc># Contents of config_dir/myconfig.cfg </cc>
- <cc>#-------------------------------------</cc>
- <cs>[HelloWorldResource]</cs>
- <ck>message</ck> = <cv>$L{localizedMessage,$RQ{person}}</cv>
- </p>
- <p class='bcode w800'>
- <cc>#-------------------------------------------</cc>
- <cc># Contents of HelloWorldResource.properties </cc>
- <cc>#-------------------------------------------</cc>
- <ck>localizedMessage</ck> = <cv>Hello {0}!</cv>
- </p>
- <p class='bcode w800'>
- <jd>/**
- * Sample REST resource that prints out a simple "Hello world!" message.
- */</jd>
- <ja>@Rest</ja>(
- messages=<js>"HelloWorldResources"</js>,
- config=<js>"config_dir/myconfig.cfg"</js>,
- ...
- )
- <jk>public class</jk> HelloWorldResource <jk>extends</jk> BasicRestServlet {
-
- <jd>/**
- * GET request handler.
- * Specify the GET parameter "?person=X" for a specialized message!
- */</jd>
- <ja>@RestGet</ja>(<js>"/"</js>)
- <jk>public</jk> String sayHello(RestRequest <jv>req</jv>) {
- <jk>return</jk> <jv>req</jv>.getConfig().getString(<js>"HelloWorldResource/message"</js>);
- }
- }
- </p>
-
- <ul class='seealso'>
- <li>{@doc juneau-config}
- </ul>
-</div>
-</div><!-- END: 6.15 - juneau-rest-server.jrs.ConfigurationFiles -->
+</div><!-- END: 6.12 - juneau-rest-server.jrs.SvlVariables -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.StaticFiles' id='juneau-rest-server.jrs.StaticFiles'>6.16 - Static files</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.16 - juneau-rest-server.jrs.StaticFiles -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.StaticFiles' id='juneau-rest-server.jrs.StaticFiles'>6.13 - Static files</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.13 - juneau-rest-server.jrs.StaticFiles -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.annotation.Rest#staticFiles @Rest(staticFiles)}
@@ -18094,12 +17863,12 @@
<li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_staticFiles}
</ul>
</div>
-</div><!-- END: 6.16 - juneau-rest-server.jrs.StaticFiles -->
+</div><!-- END: 6.13 - juneau-rest-server.jrs.StaticFiles -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ClientVersioning' id='juneau-rest-server.jrs.ClientVersioning'>6.17 - Client Versioning</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.17 - juneau-rest-server.jrs.ClientVersioning -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ClientVersioning' id='juneau-rest-server.jrs.ClientVersioning'>6.14 - Client Versioning</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.14 - juneau-rest-server.jrs.ClientVersioning -->
<div class='topic'>
<p>
Client version headers are used to support backwards compatibility for breaking REST interface changes.
@@ -18143,12 +17912,12 @@
<li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_clientVersionHeader}
</ul>
</div>
-</div><!-- END: 6.17 - juneau-rest-server.jrs.ClientVersioning -->
+</div><!-- END: 6.14 - juneau-rest-server.jrs.ClientVersioning -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.InfoProvider' id='juneau-rest-server.jrs.InfoProvider'>6.18 - RestInfoProvider</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.18 - juneau-rest-server.jrs.InfoProvider -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.InfoProvider' id='juneau-rest-server.jrs.InfoProvider'>6.15 - RestInfoProvider</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.15 - juneau-rest-server.jrs.InfoProvider -->
<div class='topic'>
<p>
The {@del org.apache.juneau.rest.RestInfoProvider} class is used to find the title
@@ -18194,12 +17963,12 @@
from the <l>BasicRestInfoProvider</l> class described next.
</p>
</div>
-</div><!-- END: 6.18 - juneau-rest-server.jrs.InfoProvider -->
+</div><!-- END: 6.15 - juneau-rest-server.jrs.InfoProvider -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger' id='juneau-rest-server.jrs.Swagger'>6.19 - Swagger</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.19 - juneau-rest-server.jrs.Swagger -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger' id='juneau-rest-server.jrs.Swagger'>6.16 - Swagger</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.16 - juneau-rest-server.jrs.Swagger -->
<div class='topic'>
<p>
One of the most useful features of Juneau is the ability to generate Swagger-based OPTIONS pages for self-documenting designs
@@ -18217,8 +17986,8 @@
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger' id='juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger'>6.19.1 - BasicRestServlet</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.1 - juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger' id='juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger'>6.16.1 - BasicRestServlet</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.1 - juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger -->
<div class='topic'>
<p>
Any subclass of {@link org.apache.juneau.rest.BasicRestServlet} gets an auto-generated Swagger UI when performing an <c>OPTIONS</c>
@@ -18295,12 +18064,12 @@
your own <ja>@RestOp</ja>-annotated method that returns a {@link org.apache.juneau.dto.swagger.Swagger} object and a {@link org.apache.juneau.dto.swagger.ui.SwaggerUI} swap.
</p>
</div>
-</div><!-- END: 6.19.1 - juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger -->
+</div><!-- END: 6.16.1 - juneau-rest-server.jrs.Swagger.jrs.BasicRestServletSwagger -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo' id='juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo'>6.19.2 - Basic Swagger Info</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.2 - juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo' id='juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo'>6.16.2 - Basic Swagger Info</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.2 - juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo -->
<div class='topic'>
<p>
Let's look at the various parts of the <c>Petstore</c> application Swagger UI to see how they are defined.
@@ -18463,12 +18232,12 @@
<li>Swagger JSON file
</ol>
</div>
-</div><!-- END: 6.19.2 - juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo -->
+</div><!-- END: 6.16.2 - juneau-rest-server.jrs.Swagger.jrs.BasicSwaggerInfo -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerTags' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerTags'>6.19.3 - Tags</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.3 - juneau-rest-server.jrs.Swagger.jrs.SwaggerTags -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerTags' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerTags'>6.16.3 - Tags</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.3 - juneau-rest-server.jrs.Swagger.jrs.SwaggerTags -->
<div class='topic'>
<p>
Tags allow you to group operations into general categories.
@@ -18565,12 +18334,12 @@
</p>
<img class='bordered w900' src='doc-files/jrs.Swagger.5.png'>
</div>
-</div><!-- END: 6.19.3 - juneau-rest-server.jrs.Swagger.jrs.SwaggerTags -->
+</div><!-- END: 6.16.3 - juneau-rest-server.jrs.Swagger.jrs.SwaggerTags -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations'>6.19.4 - Operations</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.4 - juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations'>6.16.4 - Operations</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.4 - juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations -->
<div class='topic'>
<p>
<ja>@RestOp</ja>-annotated methods automatically get rendered as Swagger operations:
@@ -18610,12 +18379,12 @@
}
</p>
</div>
-</div><!-- END: 6.19.4 - juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations -->
+</div><!-- END: 6.16.4 - juneau-rest-server.jrs.Swagger.jrs.SwaggerOperations -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters'>6.19.5 - Parameters</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.5 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters'>6.16.5 - Parameters</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.5 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters -->
<div class='topic'>
<p>
Expanding operations shows you a list of parameters:
@@ -18749,12 +18518,12 @@
Note that the schema information on the body parameter is automatically detected if not provided.
</p>
</div>
-</div><!-- END: 6.19.5 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters -->
+</div><!-- END: 6.16.5 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameters -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples'>6.19.6 - Parameter Examples</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.6 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples'>6.16.6 - Parameter Examples</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.6 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples -->
<div class='topic'>
<p>
The <c>model</c> select box in the parameters can be expanded to show examples:
@@ -18976,12 +18745,12 @@
</ul>
</ul>
</div>
-</div><!-- END: 6.19.6 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples -->
+</div><!-- END: 6.16.6 - juneau-rest-server.jrs.Swagger.jrs.SwaggerParameterExamples -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses'>6.19.7 - Responses</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.7 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses'>6.16.7 - Responses</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.7 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses -->
<div class='topic'>
<p>
Under the input parameters are listed the possible responses for the resource:
@@ -19020,12 +18789,12 @@
<li class='link'>{@doc jrs.ResponseBeans}
</ul>
</div>
-</div><!-- END: 6.19.7 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses -->
+</div><!-- END: 6.16.7 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples'>6.19.8 - Response Examples</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.8 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples'>6.16.8 - Response Examples</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.8 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples -->
<div class='topic'>
<p>
The <c>model</c> select box in the responses can be expanded to show examples:
@@ -19245,12 +19014,12 @@
}
</p>
</div>
-</div><!-- END: 6.19.8 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples -->
+</div><!-- END: 6.16.8 - juneau-rest-server.jrs.Swagger.jrs.SwaggerResponseExamples -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerModels' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerModels'>6.19.9 - Models</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.9 - juneau-rest-server.jrs.Swagger.jrs.SwaggerModels -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerModels' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerModels'>6.16.9 - Models</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.9 - juneau-rest-server.jrs.Swagger.jrs.SwaggerModels -->
<div class='topic'>
<p>
The {@del org.apache.juneau.jsonschema.JsonSchemaGenerator#JSONSCHEMA_useBeanDefs} setting can be used to reduce the size of your
@@ -19345,12 +19114,12 @@
</p>
<img class='bordered w900' src='doc-files/jrs.Swagger.Models.3.png'>
</div>
-</div><!-- END: 6.19.9 - juneau-rest-server.jrs.Swagger.jrs.SwaggerModels -->
+</div><!-- END: 6.16.9 - juneau-rest-server.jrs.Swagger.jrs.SwaggerModels -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet'>6.19.10 - SwaggerUI.css</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.19.10 - juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet' id='juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet'>6.16.10 - SwaggerUI.css</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.16.10 - juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet -->
<div class='topic'>
<p>
The look-and-feel of the Swagger UI is controlled via a single CSS file: <c>SwaggerUI.css</c>.
@@ -19361,13 +19130,13 @@
This file can be modified to change the look-and-feel of your Swagger UI.
</p>
</div>
-</div><!-- END: 6.19.10 - juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet -->
-</div><!-- END: 6.19 - juneau-rest-server.jrs.Swagger -->
+</div><!-- END: 6.16.10 - juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet -->
+</div><!-- END: 6.16 - juneau-rest-server.jrs.Swagger -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ExecutionStatistics' id='juneau-rest-server.jrs.ExecutionStatistics'>6.20 - REST method execution statistics</a><span class='update'>created: 8.1.3, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.20 - juneau-rest-server.jrs.ExecutionStatistics -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ExecutionStatistics' id='juneau-rest-server.jrs.ExecutionStatistics'>6.17 - REST method execution statistics</a><span class='update'>created: 8.1.3, <b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.17 - juneau-rest-server.jrs.ExecutionStatistics -->
<div class='topic'>
<p>
<ja>@RestResource</ja> annotated classes get automated timing and error statistic information for all <ja>@RestOp</ja>
@@ -19395,12 +19164,12 @@
</ul>
</ul>
</div>
-</div><!-- END: 6.20 - juneau-rest-server.jrs.ExecutionStatistics -->
+</div><!-- END: 6.17 - juneau-rest-server.jrs.ExecutionStatistics -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation' id='juneau-rest-server.jrs.HtmlDocAnnotation'>6.21 - @HtmlDocConfig</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.21 - juneau-rest-server.jrs.HtmlDocAnnotation -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation' id='juneau-rest-server.jrs.HtmlDocAnnotation'>6.18 - @HtmlDocConfig</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.18 - juneau-rest-server.jrs.HtmlDocAnnotation -->
<div class='topic'>
<p>
The {@link org.apache.juneau.html.annotation.HtmlDocConfig @HtmlDocConfig} annotation is used to customize the HTML
@@ -19518,8 +19287,8 @@
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI'>6.21.1 - User Interfaces (UI) vs. Developer Interfaces (DI)</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.21.1 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI'>6.18.1 - User Interfaces (UI) vs. Developer Interfaces (DI)</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.18.1 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI -->
<div class='topic'>
<p>
An important distinction needs to be made about the HTML representations produced by the REST
@@ -19562,12 +19331,12 @@
Angular, or any number of sophisticated Javascript UI frameworks. Resist the urge to do so.
</ul>
</div>
-</div><!-- END: 6.21.1 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI -->
+</div><!-- END: 6.18.1 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUIvsDI -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets'>6.21.2 - Widgets</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.21.2 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets'>6.18.2 - Widgets</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.18.2 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.widget.Widget} class allows you to add arbitrary HTML, CSS, and Javascript
@@ -19682,12 +19451,12 @@
<li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_widgets}
</ul>
</div>
-</div><!-- END: 6.21.2 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets -->
+</div><!-- END: 6.18.2 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlWidgets -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets'>6.21.3 - Predefined Widgets</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.21.3 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets'>6.18.3 - Predefined Widgets</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.18.3 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.widget} package contains predefined reusable widgets.
@@ -19924,12 +19693,12 @@
}
</p>
</div>
-</div><!-- END: 6.21.3 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets -->
+</div><!-- END: 6.18.3 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization'>6.21.4 - UI Customization</a><span class='update'><b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.21.4 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization'>6.18.4 - UI Customization</a><span class='update'><b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.18.4 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization -->
<div class='topic'>
<p>
The HTML views of POJOs can somewhat be considered a rudimentary User Interface.
@@ -20075,12 +19844,12 @@
<li class='link'>{@doc jmj.UiCustomization}
</ul>
</div>
-</div><!-- END: 6.21.4 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization -->
+</div><!-- END: 6.18.4 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlUiCustomization -->
<!-- ==================================================================================================== -->
-<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets'>6.21.5 - Stylesheets</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
-<div class='topic'><!-- START: 6.21.5 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets -->
+<h5 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets' id='juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets'>6.18.5 - Stylesheets</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></h4>
+<div class='topic'><!-- START: 6.18.5 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets -->
<div class='topic'>
<p>
The sample root page renders in the default "devops" look-and-feel:
@@ -20192,13 +19961,13 @@
}
</p>
</div>
-</div><!-- END: 6.21.5 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets -->
-</div><!-- END: 6.21 - juneau-rest-server.jrs.HtmlDocAnnotation -->
+</div><!-- END: 6.18.5 - juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlStylesheets -->
+</div><!-- END: 6.18 - juneau-rest-server.jrs.HtmlDocAnnotation -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.DefaultHeaders' id='juneau-rest-server.jrs.DefaultHeaders'>6.22 - Default Headers</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.22 - juneau-rest-server.jrs.DefaultHeaders -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.DefaultHeaders' id='juneau-rest-server.jrs.DefaultHeaders'>6.19 - Default Headers</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.19 - juneau-rest-server.jrs.DefaultHeaders -->
<div class='topic'>
<p>
The following annotations are provided for specifying default header values for requests and responses:
@@ -20242,12 +20011,12 @@
</li>
</ul>
</div>
-</div><!-- END: 6.22 - juneau-rest-server.jrs.DefaultHeaders -->
+</div><!-- END: 6.19 - juneau-rest-server.jrs.DefaultHeaders -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.LoggingAndDebugging' id='juneau-rest-server.jrs.LoggingAndDebugging'>6.23 - Logging / Debugging</a><span class='update'>created: 8.1.0, updated: 8.2.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.23 - juneau-rest-server.jrs.LoggingAndDebugging -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.LoggingAndDebugging' id='juneau-rest-server.jrs.LoggingAndDebugging'>6.20 - Logging / Debugging</a><span class='update'>created: 8.1.0, updated: 8.2.0, <b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.20 - juneau-rest-server.jrs.LoggingAndDebugging -->
<div class='topic'>
<p>
The REST APIs provides support for fine-tuned control of logging for HTTP requests and responses.
@@ -20580,12 +20349,12 @@
to the log file again.
</p>
</div>
-</div><!-- END: 6.23 - juneau-rest-server.jrs.LoggingAndDebugging -->
+</div><!-- END: 6.20 - juneau-rest-server.jrs.LoggingAndDebugging -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HttpStatusCodes' id='juneau-rest-server.jrs.HttpStatusCodes'>6.24 - HTTP Status Codes</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.24 - juneau-rest-server.jrs.HttpStatusCodes -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.HttpStatusCodes' id='juneau-rest-server.jrs.HttpStatusCodes'>6.21 - HTTP Status Codes</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.21 - juneau-rest-server.jrs.HttpStatusCodes -->
<div class='topic'>
<p>
By default, a 200 (OK) status is automatically set as the HTTP status when a Java method executes
@@ -20650,12 +20419,12 @@
</tr>
</table>
</div>
-</div><!-- END: 6.24 - juneau-rest-server.jrs.HttpStatusCodes -->
+</div><!-- END: 6.21 - juneau-rest-server.jrs.HttpStatusCodes -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.OverloadingHttpMethods' id='juneau-rest-server.jrs.OverloadingHttpMethods'>6.25 - Overloading HTTP Methods</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.25 - juneau-rest-server.jrs.OverloadingHttpMethods -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.OverloadingHttpMethods' id='juneau-rest-server.jrs.OverloadingHttpMethods'>6.22 - Overloading HTTP Methods</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.22 - juneau-rest-server.jrs.OverloadingHttpMethods -->
<div class='topic'>
<p>
Through the use of the built-in <l>"method"</l> GET parameter, you can implement requests beyond the basic
@@ -20681,12 +20450,12 @@
)
</p>
</div>
-</div><!-- END: 6.25 - juneau-rest-server.jrs.OverloadingHttpMethods -->
+</div><!-- END: 6.22 - juneau-rest-server.jrs.OverloadingHttpMethods -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.BuiltInParameters' id='juneau-rest-server.jrs.BuiltInParameters'>6.26 - Built-in Parameters</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.26 - juneau-rest-server.jrs.BuiltInParameters -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.BuiltInParameters' id='juneau-rest-server.jrs.BuiltInParameters'>6.23 - Built-in Parameters</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.23 - juneau-rest-server.jrs.BuiltInParameters -->
<div class='topic'>
<p>
The following URL parameters have special meaning and can be passed in through the URL of the request:
@@ -20748,12 +20517,12 @@
</tr>
</table>
</div>
-</div><!-- END: 6.26 - juneau-rest-server.jrs.BuiltInParameters -->
+</div><!-- END: 6.23 - juneau-rest-server.jrs.BuiltInParameters -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.CustomSerializersAndParsers' id='juneau-rest-server.jrs.CustomSerializersAndParsers'>6.27 - Custom Serializers and Parsers</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.27 - juneau-rest-server.jrs.CustomSerializersAndParsers -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.CustomSerializersAndParsers' id='juneau-rest-server.jrs.CustomSerializersAndParsers'>6.24 - Custom Serializers and Parsers</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.24 - juneau-rest-server.jrs.CustomSerializersAndParsers -->
<div class='topic'>
<p>
A very easy-to-use API is provided for defining your own serializers and parsers at both the servlet and
@@ -20870,12 +20639,12 @@
}
</p>
</div>
-</div><!-- END: 6.27 - juneau-rest-server.jrs.CustomSerializersAndParsers -->
+</div><!-- END: 6.24 - juneau-rest-server.jrs.CustomSerializersAndParsers -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.UsingWithOsgi' id='juneau-rest-server.jrs.UsingWithOsgi'>6.28 - Using with OSGi</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.28 - juneau-rest-server.jrs.UsingWithOsgi -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.UsingWithOsgi' id='juneau-rest-server.jrs.UsingWithOsgi'>6.25 - Using with OSGi</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.25 - juneau-rest-server.jrs.UsingWithOsgi -->
<div class='topic'>
<p>
Since REST servlets are basically just <l>HttpServlets</l>, incorporating them into an OSGi environment
@@ -20939,12 +20708,12 @@
}
</p>
</div>
-</div><!-- END: 6.28 - juneau-rest-server.jrs.UsingWithOsgi -->
+</div><!-- END: 6.25 - juneau-rest-server.jrs.UsingWithOsgi -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Injection' id='juneau-rest-server.jrs.Injection'>6.29 - Using with Spring and Injection frameworks</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.29 - juneau-rest-server.jrs.Injection -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Injection' id='juneau-rest-server.jrs.Injection'>6.26 - Using with Spring and Injection frameworks</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.26 - juneau-rest-server.jrs.Injection -->
<div class='topic'>
<p>
The Juneau REST server API is compatible with dependency injection frameworks such as Spring.
@@ -21048,12 +20817,12 @@
}
</p>
</div>
-</div><!-- END: 6.29 - juneau-rest-server.jrs.Injection -->
+</div><!-- END: 6.26 - juneau-rest-server.jrs.Injection -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.OtherNotes' id='juneau-rest-server.jrs.OtherNotes'>6.30 - Other Notes</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.30 - juneau-rest-server.jrs.OtherNotes -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.OtherNotes' id='juneau-rest-server.jrs.OtherNotes'>6.27 - Other Notes</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.27 - juneau-rest-server.jrs.OtherNotes -->
<div class='topic'>
<ul class='spaced-list'>
<li>
@@ -21066,12 +20835,12 @@
parameter can be specified: <l>"/sample?X-Response-Headers={Refresh=1}"</l>
</ul>
</div>
-</div><!-- END: 6.30 - juneau-rest-server.jrs.OtherNotes -->
+</div><!-- END: 6.27 - juneau-rest-server.jrs.OtherNotes -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.RestContext' id='juneau-rest-server.jrs.RestContext'>6.31 - RestContext</a><span class='update'><b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.31 - juneau-rest-server.jrs.RestContext -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.RestContext' id='juneau-rest-server.jrs.RestContext'>6.28 - RestContext</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.28 - juneau-rest-server.jrs.RestContext -->
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.RestContext} object is the workhorse class for all of the configuration
@@ -21121,12 +20890,12 @@
resource finders, info providers, etc...
</p>
</div>
-</div><!-- END: 6.31 - juneau-rest-server.jrs.RestContext -->
+</div><!-- END: 6.28 - juneau-rest-server.jrs.RestContext -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.RestRpc' id='juneau-rest-server.jrs.RestRpc'>6.32 - REST/RPC</a><span class='update'>updated: 8.0.0, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.32 - juneau-rest-server.jrs.RestRpc -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.RestRpc' id='juneau-rest-server.jrs.RestRpc'>6.29 - REST/RPC</a><span class='update'>updated: 8.0.0, <b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.29 - juneau-rest-server.jrs.RestRpc -->
<div class='topic'>
<p>
The REST/RPC (RPC over REST) API allows the creation of client-side remote proxy interfaces for calling methods on server-side POJOs using entirely REST.
@@ -21447,12 +21216,12 @@
<h5 class='figure'>Sample form entry page results</h5>
<img class='bordered w800' src='doc-files/jrs.restRPC.9.png'>
</div>
-</div><!-- END: 6.32 - juneau-rest-server.jrs.RestRpc -->
+</div><!-- END: 6.29 - juneau-rest-server.jrs.RestRpc -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.CustomRestContextsAndBuilders' id='juneau-rest-server.jrs.CustomRestContextsAndBuilders'>6.33 - Custom REST Context and Builders</a><span class='update'>created: <b>9.0.0</b>, <b><red>todo</red></b></span></h3>
-<div class='topic'><!-- START: 6.33 - juneau-rest-server.jrs.CustomRestContextsAndBuilders -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.CustomRestContextsAndBuilders' id='juneau-rest-server.jrs.CustomRestContextsAndBuilders'>6.30 - Custom REST Context and Builders</a><span class='update'>created: <b>9.0.0</b>, <b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.30 - juneau-rest-server.jrs.CustomRestContextsAndBuilders -->
<div class='topic'>
<p>
They can also be defined programmatically:
@@ -21486,51 +21255,138 @@
}
</p>
</div>
-</div><!-- END: 6.33 - juneau-rest-server.jrs.CustomRestContextsAndBuilders -->
+</div><!-- END: 6.30 - juneau-rest-server.jrs.CustomRestContextsAndBuilders -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.FluentAssertions' id='juneau-rest-server.jrs.FluentAssertions'>6.34 - Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
-<div class='topic'><!-- START: 6.34 - juneau-rest-server.jrs.FluentAssertions -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.FluentAssertions' id='juneau-rest-server.jrs.FluentAssertions'>6.31 - Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
+<div class='topic'><!-- START: 6.31 - juneau-rest-server.jrs.FluentAssertions -->
<div class='topic'>
<p>
TODO
</p>
</div>
-</div><!-- END: 6.34 - juneau-rest-server.jrs.FluentAssertions -->
+</div><!-- END: 6.31 - juneau-rest-server.jrs.FluentAssertions -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Overview' id='juneau-rest-server.jrs.Overview'>6.35 - Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
-<div class='topic'><!-- START: 6.35 - juneau-rest-server.jrs.Overview -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.Overview' id='juneau-rest-server.jrs.Overview'>6.32 - Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
+<div class='topic'><!-- START: 6.32 - juneau-rest-server.jrs.Overview -->
<div class='topic'>
<p>
TODO
</p>
</div>
-</div><!-- END: 6.35 - juneau-rest-server.jrs.Overview -->
+</div><!-- END: 6.32 - juneau-rest-server.jrs.Overview -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ResponseProcessors' id='juneau-rest-server.jrs.ResponseProcessors'>6.36 - Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
-<div class='topic'><!-- START: 6.36 - juneau-rest-server.jrs.ResponseProcessors -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.ResponseProcessors' id='juneau-rest-server.jrs.ResponseProcessors'>6.33 - Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
+<div class='topic'><!-- START: 6.33 - juneau-rest-server.jrs.ResponseProcessors -->
<div class='topic'>
<p>
TODO
</p>
</div>
-</div><!-- END: 6.36 - juneau-rest-server.jrs.ResponseProcessors -->
+</div><!-- END: 6.33 - juneau-rest-server.jrs.ResponseProcessors -->
<!-- ==================================================================================================== -->
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.UtilityBeans' id='juneau-rest-server.jrs.UtilityBeans'>6.37 - Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
-<div class='topic'><!-- START: 6.37 - juneau-rest-server.jrs.UtilityBeans -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.UtilityBeans' id='juneau-rest-server.jrs.UtilityBeans'>6.34 - Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></h3>
+<div class='topic'><!-- START: 6.34 - juneau-rest-server.jrs.UtilityBeans -->
<div class='topic'>
<p>
TODO
</p>
</div>
-</div><!-- END: 6.37 - juneau-rest-server.jrs.UtilityBeans -->
+</div><!-- END: 6.34 - juneau-rest-server.jrs.UtilityBeans -->
+
+<!-- ==================================================================================================== -->
+
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.jrs.SerializingUris' id='juneau-rest-server.jrs.SerializingUris'>6.35 - URIs</a><span class='update'><b><red>todo</red></b></span></h3>
+<div class='topic'><!-- START: 6.35 - juneau-rest-server.jrs.SerializingUris -->
+<div class='topic'>
+ <p>
+ As mention earlier {@doc jm.MarshallingUris here}, Juneau serializers have sophisticated support for transforming relative URIs to absolute form.
+ </p>
+ <p>
+ The following example shows a REST method that returns a list of URIs of various forms:
+ </p>
+ <p class='bcode w800'>
+ <ja>@Rest</ja>(
+ uriAuthority=<js>"http://foo.com:123"</js>,
+ uriContext=<js>"/myContext"</js>
+ )
+ <jk>public class</jk> MyResource {
+
+ <ja>@RestGet</ja>
+ <jk>public</jk> URI[] getURIs() {
+ <jk>return new</jk> URI[] {
+ URI.<jsm>create</jsm>(<js>"http://www.apache.org/f1a"</js>),
+ URI.<jsm>create</jsm>(<js>"/f1b"</js>),
+ URI.<jsm>create</jsm>(<js>"/f1c/x/y"</js>),
+ URI.<jsm>create</jsm>(<js>"f1d"</js>),
+ URI.<jsm>create</jsm>(<js>"f1e/x/y"</js>),
+ URI.<jsm>create</jsm>(<js>""</js>),
+ URI.<jsm>create</jsm>(<js>"context:/f2a/x"</js>),
+ URI.<jsm>create</jsm>(<js>"context:/f2b"</js>),
+ URI.<jsm>create</jsm>(<js>"context:/"</js>),
+ URI.<jsm>create</jsm>(<js>"context:/.."</js>),
+ URI.<jsm>create</jsm>(<js>"servlet:/f3a/x"</js>),
+ URI.<jsm>create</jsm>(<js>"servlet:/f3b"</js>),
+ URI.<jsm>create</jsm>(<js>"servlet:/"</js>),
+ URI.<jsm>create</jsm>(<js>"servlet:/.."</js>),
+ URI.<jsm>create</jsm>(<js>"request:/f4a/x"</js>),
+ URI.<jsm>create</jsm>(<js>"request:/f4b"</js>),
+ URI.<jsm>create</jsm>(<js>"request:/"</js>),
+ URI.<jsm>create</jsm>(<js>"request:/.."</js>)
+ };
+ }
+ }
+ </p>
+ <p>
+ When requested as JSON, it produces the following result:
+ </p>
+ <p class='bcode w800'>
+ {
+ <jok>f1a</jok>:<jov>'http://www.apache.org/f1a'</jov>,
+ <jok>f1b</jok>:<jov>'http://foo.com:123/f1b'</jov>,
+ <jok>f1c</jok>:<jov>'http://foo.com:123/f1c/x/y'</jov>,
+ <jok>f1d</jok>:<jov>'http://foo.com:123/myContext/myServlet/f1d'</jov>,
+ <jok>f1e</jok>:<jov>'http://foo.com:123/myContext/myServlet/f1e/x/y'</jov>,
+ <jok>f1f</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>,
+ <jok>f2a</jok>:<jov>'http://foo.com:123/myContext/f2a/x'</jov>,
+ <jok>f2b</jok>:<jov>'http://foo.com:123/myContext/f2b'</jov>,
+ <jok>f2c</jok>:<jov>'http://foo.com:123/myContext'</jov>,
+ <jok>f2d</jok>:<jov>'http://foo.com:123'</jov>,
+ <jok>f3a</jok>:<jov>'http://foo.com:123/myContext/myServlet/f3a/x'</jov>,
+ <jok>f3b</jok>:<jov>'http://foo.com:123/myContext/myServlet/f3b'</jov>,
+ <jok>f3c</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>,
+ <jok>f3d</jok>:<jov>'http://foo.com:123/myContext'</jov>,
+ <jok>f4a</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath/f4a/x'</jov>,
+ <jok>f4b</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath/f4b'</jov>,
+ <jok>f4c</jok>:<jov>'http://foo.com:123/myContext/myServlet/myPath'</jov>,
+ <jok>f4d</jok>:<jov>'http://foo.com:123/myContext/myServlet'</jov>
+ }
+ </p>
+ <p>
+ URI resolution is controlled by the following settings:
+ </p>
+ <ul class='javatree'>
+ <li class='jc'>{@link org.apache.juneau.rest.RestContext}
+ <ul>
+ <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriAuthority REST_uriAuthority}
+ <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriContext REST_uriContext}
+ <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriRelativity REST_uriRelativity}
+ <li class='jf'>{@del org.apache.juneau.rest.RestContext#REST_uriResolution REST_uriResolution}
+ </ul>
+ </ul>
+
+ <p>
+ URIs are resolved by both regular and part serializers.
+ </p>
+</div>
+</div><!-- END: 6.35 - juneau-rest-server.jrs.SerializingUris -->
</div><!-- END: 6 - juneau-rest-server -->
<!-- ==================================================================================================== -->
diff --git a/juneau-doc/src/main/javadoc/resources/docs.txt b/juneau-doc/src/main/javadoc/resources/docs.txt
index edbf8da..b446473 100644
--- a/juneau-doc/src/main/javadoc/resources/docs.txt
+++ b/juneau-doc/src/main/javadoc/resources/docs.txt
@@ -268,7 +268,6 @@ jrs.ExecutionStatistics = #juneau-rest-server.jrs.ExecutionStatistics, Overview
jrs.FluentAssertions = #juneau-rest-server.jrs.FluentAssertions, Overview > juneau-rest-server > Fluent Assertions
jrs.Guards = #juneau-rest-server.jrs.Guards, Overview > juneau-rest-server > Guards
jrs.HandlingFormPosts = #juneau-rest-server.jrs.HandlingFormPosts, Overview > juneau-rest-server > Form Posts
-jrs.HandlingUris = #juneau-rest-server.jrs.HandlingUris, Overview > juneau-rest-server > URIs
jrs.HelloWorldExample = #juneau-rest-server.jrs.HelloWorldExample, Overview > juneau-rest-server > Hello World Example
jrs.HtmlDocAnnotation = #juneau-rest-server.jrs.HtmlDocAnnotation, Overview > juneau-rest-server > @HtmlDocConfig
jrs.HtmlPredefinedWidgets = #juneau-rest-server.jrs.HtmlDocAnnotation.jrs.HtmlPredefinedWidgets, Overview > juneau-rest-server > @HtmlDocConfig > Predefined Widgets
@@ -287,10 +286,10 @@ jrs.JavaMethodParameters = #juneau-rest-server.jrs.RestOpAnnotatedMethods.jrs.Ja
jrs.JavaMethodReturnTypes = #juneau-rest-server.jrs.RestOpAnnotatedMethods.jrs.JavaMethodReturnTypes, Overview > juneau-rest-server > @RestOp-Annotated Methods > Java Method Return Types
jrs.JavaMethodThrowableTypes = #juneau-rest-server.jrs.RestOpAnnotatedMethods.jrs.JavaMethodThrowableTypes, Overview > juneau-rest-server > @RestOp-Annotated Methods > Java Method Throwable Types
jrs.LifecycleHooks = #juneau-rest-server.jrs.AnnotatedClasses.jrs.LifecycleHooks, Overview > juneau-rest-server > @Rest-Annotated Classes > Lifecycle Hooks
+jrs.LocalizedMessages = #juneau-rest-server.jrs.LocalizedMessages, Overview > juneau-rest-server > Localized Messages
jrs.LoggingAndDebugging = #juneau-rest-server.jrs.LoggingAndDebugging, Overview > juneau-rest-server > Logging / Debugging
jrs.Marshalling = #juneau-rest-server.jrs.Marshalling, Overview > juneau-rest-server > Marshalling
jrs.Matchers = #juneau-rest-server.jrs.RestOpAnnotatedMethods.jrs.Matchers, Overview > juneau-rest-server > @RestOp-Annotated Methods > Matchers
-jrs.Messages = #juneau-rest-server.jrs.Messages, Overview > juneau-rest-server > Messages
jrs.OtherNotes = #juneau-rest-server.jrs.OtherNotes, Overview > juneau-rest-server > Other Notes
jrs.OverloadingHttpMethods = #juneau-rest-server.jrs.OverloadingHttpMethods, Overview > juneau-rest-server > Overloading HTTP Methods
jrs.Overview = #juneau-rest-server.jrs.Overview, Overview > juneau-rest-server > Utility Beans
@@ -302,7 +301,7 @@ jrs.ResponseProcessors = #juneau-rest-server.jrs.ResponseProcessors, Overview >
jrs.RestContext = #juneau-rest-server.jrs.RestContext, Overview > juneau-rest-server > RestContext
jrs.RestOpAnnotatedMethods = #juneau-rest-server.jrs.RestOpAnnotatedMethods, Overview > juneau-rest-server > @RestOp-Annotated Methods
jrs.RestRpc = #juneau-rest-server.jrs.RestRpc, Overview > juneau-rest-server > REST/RPC
-jrs.RoleGuards = #juneau-rest-server.jrs.RoleGuards, Overview > juneau-rest-server > Role guards
+jrs.SerializingUris = #juneau-rest-server.jrs.SerializingUris, Overview > juneau-rest-server > URIs
jrs.StaticFiles = #juneau-rest-server.jrs.StaticFiles, Overview > juneau-rest-server > Static files
jrs.SvlVariables = #juneau-rest-server.jrs.SvlVariables, Overview > juneau-rest-server > SVL Variables
jrs.Swagger = #juneau-rest-server.jrs.Swagger, Overview > juneau-rest-server > Swagger
@@ -314,7 +313,6 @@ jrs.SwaggerResponseExamples = #juneau-rest-server.jrs.Swagger.jrs.SwaggerRespons
jrs.SwaggerResponses = #juneau-rest-server.jrs.Swagger.jrs.SwaggerResponses, Overview > juneau-rest-server > Swagger > Responses
jrs.SwaggerStylesheet = #juneau-rest-server.jrs.Swagger.jrs.SwaggerStylesheet, Overview > juneau-rest-server > Swagger > SwaggerUI.css
jrs.SwaggerTags = #juneau-rest-server.jrs.Swagger.jrs.SwaggerTags, Overview > juneau-rest-server > Swagger > Tags
-jrs.Transforms = #juneau-rest-server.jrs.Transforms, Overview > juneau-rest-server > Transforms
jrs.UsingWithOsgi = #juneau-rest-server.jrs.UsingWithOsgi, Overview > juneau-rest-server > Using with OSGi
jrs.UtilityBeans = #juneau-rest-server.jrs.UtilityBeans, Overview > juneau-rest-server > Utility Beans
jrsj.BaseProvider = #juneau-rest-server-jaxrs.jrsj.BaseProvider, Overview > juneau-rest-server-jaxrs > Juneau JAX-RS Provider
diff --git a/juneau-doc/src/main/javadoc/resources/fragments/toc.html b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
index 4766e60..0cd408b 100644
--- a/juneau-doc/src/main/javadoc/resources/fragments/toc.html
+++ b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
@@ -229,15 +229,12 @@
</ol>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Marshalling'>Marshalling</a><span class='update'>updated: <b>9.0.0</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.HandlingFormPosts'>Form Posts</a><span class='update'>updated: <b>9.0.0</b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Transforms'>Transforms</a><span class='update'>updated: 8.1.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.HandlingUris'>URIs</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Guards'>Guards</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.RoleGuards'>Role guards</a><span class='update'>created: 8.1.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Converters'>Converters</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Messages'>Messages</a><span class='update'>updated: 8.2.0, <b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Encoders'>Encoders</a><span class='update'><b><red>todo</red></b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Guards'>Guards</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Converters'>Converters</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.LocalizedMessages'>Localized Messages</a><span class='update'>updated: 8.2.0,<b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Encoders'>Encoders</a><span class='update'>updated: <b>9.0.0</b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.ConfigurationFiles'>Configuration Files</a><span class='update'>updated: <b>9.0.0</b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.SvlVariables'>SVL Variables</a><span class='update'><b><red>todo</red></b></span></p>
- <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.ConfigurationFiles'>Configuration Files</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.StaticFiles'>Static files</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.ClientVersioning'>Client Versioning</a><span class='update'><b><red>todo</red></b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.InfoProvider'>RestInfoProvider</a><span class='update'><b><red>todo</red></b></span></p>
@@ -279,6 +276,7 @@
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.Overview'>Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.ResponseProcessors'>Fluent Assertions</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.UtilityBeans'>Utility Beans</a><span class='update'>created: <b>9.0.0</b>, <b><red>TODO</red></b></span></p>
+ <li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.jrs.SerializingUris'>URIs</a><span class='update'><b><red>todo</red></b></span></p>
</ol>
<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server-rdf'>juneau-rest-server-jaxrs</a></p>
<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</a></p>
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
index 43085b4..eeab7c6 100755
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
@@ -649,7 +649,7 @@ public class Microservice implements ConfigEventListener {
// --------------------------------------------------------------------------------
// Initialize console commands.
// --------------------------------------------------------------------------------
- this.consoleEnabled = ObjectUtils.firstNonNull(builder.consoleEnabled, config.getBoolean("Console/enabled", false));
+ this.consoleEnabled = ObjectUtils.firstNonNull(builder.consoleEnabled, config.get("Console/enabled").asBoolean().orElse(false));
if (consoleEnabled) {
Console c = System.console();
this.consoleReader = ObjectUtils.firstNonNull(builder.consoleReader, new Scanner(c == null ? new InputStreamReader(System.in) : c.reader()));
@@ -658,7 +658,7 @@ public class Microservice implements ConfigEventListener {
for (ConsoleCommand cc : builder.consoleCommands) {
consoleCommandMap.put(cc.getName(), cc);
}
- for (String s : config.getStringArray("Console/commands")) {
+ for (String s : config.get("Console/commands").asStringArray().orElse(new String[0])) {
ConsoleCommand cc;
try {
cc = (ConsoleCommand)Class.forName(s).newInstance();
@@ -760,7 +760,7 @@ public class Microservice implements ConfigEventListener {
Set<String> spKeys = config.getKeys("SystemProperties");
if (spKeys != null)
for (String key : spKeys)
- System.setProperty(key, config.getString("SystemProperties/"+key));
+ System.setProperty(key, config.get("SystemProperties/"+key).orElse(null));
// --------------------------------------------------------------------------------
// Initialize logging.
@@ -770,43 +770,42 @@ public class Microservice implements ConfigEventListener {
if (this.logger == null) {
LogManager.getLogManager().reset();
this.logger = Logger.getLogger("");
- String logFile = firstNonNull(logConfig.logFile, config.getString("Logging/logFile"));
+ String logFile = firstNonNull(logConfig.logFile, config.get("Logging/logFile").orElse(null));
if (isNotEmpty(logFile)) {
- String logDir = firstNonNull(logConfig.logDir, config.getString("Logging/logDir", "."));
+ String logDir = firstNonNull(logConfig.logDir, config.get("Logging/logDir").orElse("."));
File logDirFile = resolveFile(logDir);
mkdirs(logDirFile, false);
logDir = logDirFile.getAbsolutePath();
System.setProperty("juneau.logDir", logDir);
- boolean append = firstNonNull(logConfig.append, config.getBoolean("Logging/append"));
- int limit = firstNonNull(logConfig.limit, config.getInt("Logging/limit", 1024*1024));
- int count = firstNonNull(logConfig.count, config.getInt("Logging/count", 1));
+ boolean append = firstNonNull(logConfig.append, config.get("Logging/append").asBoolean().orElse(false));
+ int limit = firstNonNull(logConfig.limit, config.get("Logging/limit").asInteger().orElse(1024*1024));
+ int count = firstNonNull(logConfig.count, config.get("Logging/count").asInteger().orElse(1));
FileHandler fh = new FileHandler(logDir + '/' + logFile, limit, count, append);
Formatter f = logConfig.formatter;
if (f == null) {
- String format = config.getString("Logging/format", "[{date} {level}] {msg}%n");
- String dateFormat = config.getString("Logging/dateFormat", "yyyy.MM.dd hh:mm:ss");
- boolean useStackTraceHashes = config.getBoolean("Logging/useStackTraceHashes");
+ String format = config.get("Logging/format").orElse("[{date} {level}] {msg}%n");
+ String dateFormat = config.get("Logging/dateFormat").orElse("yyyy.MM.dd hh:mm:ss");
+ boolean useStackTraceHashes = config.get("Logging/useStackTraceHashes").asBoolean().orElse(false);
f = new LogEntryFormatter(format, dateFormat, useStackTraceHashes);
}
fh.setFormatter(f);
- fh.setLevel(firstNonNull(logConfig.fileLevel, config.getObjectWithDefault("Logging/fileLevel", Level.INFO, Level.class)));
+ fh.setLevel(firstNonNull(logConfig.fileLevel, config.get("Logging/fileLevel").as(Level.class).orElse(Level.INFO)));
logger.addHandler(fh);
ConsoleHandler ch = new ConsoleHandler();
- ch.setLevel(firstNonNull(logConfig.consoleLevel, config.getObjectWithDefault("Logging/consoleLevel", Level.WARNING, Level.class)));
+ ch.setLevel(firstNonNull(logConfig.consoleLevel, config.get("Logging/consoleLevel").as(Level.class).orElse(Level.WARNING)));
ch.setFormatter(f);
logger.addHandler(ch);
}
}
- OMap loggerLevels = config.getObject("Logging/levels", OMap.class);
- if (loggerLevels != null)
- for (String l : loggerLevels.keySet())
- Logger.getLogger(l).setLevel(loggerLevels.get(l, Level.class));
+ OMap loggerLevels = config.get("Logging/levels").as(OMap.class).orElseGet(OMap::new);
+ for (String l : loggerLevels.keySet())
+ Logger.getLogger(l).setLevel(loggerLevels.get(l, Level.class));
for (String l : logConfig.levels.keySet())
Logger.getLogger(l).setLevel(logConfig.levels.get(l));
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/console/ConfigCommand.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/console/ConfigCommand.java
index 1952085..6e70e85 100644
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/console/ConfigCommand.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/console/ConfigCommand.java
@@ -61,7 +61,7 @@ public class ConfigCommand extends ConsoleCommand {
if (option.equals("get")) {
// config get <key>
if (args.size() == 3) {
- String val = conf.getString(key);
+ String val = conf.get(key).orElse(null);
if (val != null)
out.println(val);
else
@@ -82,7 +82,7 @@ public class ConfigCommand extends ConsoleCommand {
} else if (option.equals("remove")) {
// config remove <key>
if (args.size() == 3) {
- if (conf.getString(key) != null) {
+ if (conf.get(key).isPresent()) {
conf.remove(key);
out.println(mb.getString("ConfigRemove", key));
} else {
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
index d52c020..acac476 100755
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
@@ -114,10 +114,10 @@ public class DirectoryResource extends BasicRestServlet {
final boolean allowDeletes, allowUploads, allowViews;
public DirectoryResource(Config c) throws Exception {
- rootDir = new File(c.getString(DIRECTORY_RESOURCE_rootDir, "."));
- allowViews = c.getBoolean(DIRECTORY_RESOURCE_allowViews, false);
- allowDeletes = c.getBoolean(DIRECTORY_RESOURCE_allowDeletes, false);
- allowUploads = c.getBoolean(DIRECTORY_RESOURCE_allowUploads, false);
+ rootDir = new File(c.get(DIRECTORY_RESOURCE_rootDir).orElse("."));
+ allowViews = c.get(DIRECTORY_RESOURCE_allowViews).asBoolean().orElse(false);
+ allowDeletes = c.get(DIRECTORY_RESOURCE_allowDeletes).asBoolean().orElse(false);
+ allowUploads = c.get(DIRECTORY_RESOURCE_allowUploads).asBoolean().orElse(false);
}
@RestGet(
diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
index fabca60..c518503 100755
--- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
+++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java
@@ -93,12 +93,12 @@ public class LogsResource extends BasicRestServlet {
final boolean allowDeletes;
public LogsResource(Config c) {
- logDir = new File(c.getString(LOGS_RESOURCE_logDir, "logDir"));
- allowDeletes = c.getBoolean(LOGS_RESOURCE_allowDeletes, true);
+ logDir = new File(c.get(LOGS_RESOURCE_logDir).orElse("logDir"));
+ allowDeletes = c.get(LOGS_RESOURCE_allowDeletes).asBoolean().orElse(true);
leFormatter = new LogEntryFormatter(
- c.getString(LOGS_RESOURCE_logFormat, "[{date} {level}] {msg}%n"),
- c.getString(LOGS_RESOURCE_dateFormat, "yyyy.MM.dd hh:mm:ss"),
- c.getBoolean(LOGS_RESOURCE_useStackTraceHashes, true)
+ c.get(LOGS_RESOURCE_logFormat).orElse("[{date} {level}] {msg}%n"),
+ c.get(LOGS_RESOURCE_dateFormat).orElse("yyyy.MM.dd hh:mm:ss"),
+ c.get(LOGS_RESOURCE_useStackTraceHashes).asBoolean().orElse(true)
);
}
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigResource.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
index a51c22e..717e81c 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigResource.java
@@ -34,6 +34,6 @@ public class ConfigResource extends BasicRestServlet {
@RestOp(method=GET, path="/{key}/{class}")
public Object test2(RestRequest req, @Path("key") String key, @Path("class") Class<?> c) throws Exception {
- return req.getConfig().getObject(key, c);
+ return req.getConfig().get(key).as(c).orElse(null);
}
}
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
index 146a6f1..c506af1 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
@@ -159,7 +159,7 @@ public class TestMicroservice {
private static int dumpCount = 0;
public static void jettyDump(RequestLine rl, StatusLine sl) {
- try (FileWriter fw = new FileWriter(microservice.getConfig().getString("Logging/logDir") + "/jetty-thread-dump-"+(dumpCount++)+".log")) {
+ try (FileWriter fw = new FileWriter(microservice.getConfig().get("Logging/logDir").orElse("") + "/jetty-thread-dump-"+(dumpCount++)+".log")) {
String dump = microservice.getServer().dump();
fw.append("RequestLine = [" + rl + "]\n");
fw.append("StatusLine = [" + sl + "]\n");
diff --git a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
index 3fc71e9..70f1350 100644
--- a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
+++ b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java
@@ -670,15 +670,15 @@ public class JettyMicroservice extends Microservice {
OMap mf = getManifest();
VarResolver vr = getVarResolver();
- int[] ports = ObjectUtils.firstNonNull(builder.ports, cf.getObjectWithDefault("Jetty/port", mf.getWithDefault("Jetty-Port", new int[]{8000}, int[].class), int[].class));
+ int[] ports = ObjectUtils.firstNonNull(builder.ports, cf.get("Jetty/port").as(int[].class).orElseGet(()->mf.getWithDefault("Jetty-Port", new int[]{8000}, int[].class)));
int availablePort = findOpenPort(ports);
if (System.getProperty("availablePort") == null)
System.setProperty("availablePort", String.valueOf(availablePort));
String jettyXml = builder.jettyXml;
- String jettyConfig = cf.getString("Jetty/config", mf.getString("Jetty-Config", "jetty.xml"));
- boolean resolveVars = ObjectUtils.firstNonNull(builder.jettyXmlResolveVars, cf.getBoolean("Jetty/resolveVars"));
+ String jettyConfig = cf.get("Jetty/config").orElse(mf.getString("Jetty-Config", "jetty.xml"));
+ boolean resolveVars = ObjectUtils.firstNonNull(builder.jettyXmlResolveVars, cf.get("Jetty/resolveVars").asBoolean().orElse(false));
if (jettyXml == null)
jettyXml = IOUtils.loadSystemResourceAsString("jetty.xml", ".", "files");
@@ -696,7 +696,7 @@ public class JettyMicroservice extends Microservice {
throw new ExecutableException(e2);
}
- for (String s : cf.getStringArray("Jetty/servlets", new String[0])) {
+ for (String s : cf.get("Jetty/servlets").asStringArray().orElse(new String[0])) {
try {
ClassInfo c = ClassInfo.of(Class.forName(s));
if (c.isChildOf(RestServlet.class)) {
@@ -710,7 +710,7 @@ public class JettyMicroservice extends Microservice {
}
}
- for (Map.Entry<String,Object> e : cf.getMap("Jetty/servletMap", OMap.EMPTY_MAP).entrySet()) {
+ for (Map.Entry<String,Object> e : cf.get("Jetty/servletMap").asMap().orElse(OMap.EMPTY_MAP).entrySet()) {
try {
ClassInfo c = ClassInfo.of(Class.forName(e.getValue().toString()));
if (c.isChildOf(Servlet.class)) {
@@ -724,7 +724,7 @@ public class JettyMicroservice extends Microservice {
}
}
- for (Map.Entry<String,Object> e : cf.getMap("Jetty/servletAttributes", OMap.EMPTY_MAP).entrySet())
+ for (Map.Entry<String,Object> e : cf.get("Jetty/servletAttributes").asMap().orElse(OMap.EMPTY_MAP).entrySet())
addServletAttribute(e.getKey(), e.getValue());
for (Map.Entry<String,Servlet> e : builder.servlets.entrySet())
diff --git a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
index 728ed53..ff97b3d 100644
--- a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
+++ b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
@@ -76,7 +76,7 @@ public class DebugResource extends BasicRestServlet {
@RestPost(path="/jetty/dump", description="Generates and saves the jetty thread dump file to jetty-thread-dump.log.")
public String createJettyDump(RestRequest req, RestResponse res) throws Exception {
String dump = JettyMicroservice.getInstance().getServer().dump();
- try (FileWriter fw = new FileWriter(req.getConfig().getString("Logging/logDir") + "/jetty-thread-dump.log")) {
+ try (FileWriter fw = new FileWriter(req.getConfig().get("Logging/logDir").orElse("") + "/jetty-thread-dump.log")) {
fw.write(dump);
}
return "OK";
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
index c9f4534..511a650 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
@@ -172,7 +172,7 @@ public abstract class BasicSpringRestServlet extends SpringRestServlet implement
@Override /* BasicRestConfig */
public HttpResource getFavIcon() {
- String favIcon = getContext().getConfig().getString("REST/favicon", "images/juneau.png");
+ String favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
return getHtdoc(favIcon, null);
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
index 950e6df..5c82718 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestObject.java
@@ -59,7 +59,7 @@ public abstract class BasicRestObject extends RestObject implements BasicUnivers
@Override /* BasicRestOperations */
public HttpResource getFavIcon() {
- String favIcon = getContext().getConfig().getString("REST/favicon", "images/juneau.png");
+ String favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
return getHtdoc(favIcon, null);
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
index ec2e95b..016505b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
@@ -156,7 +156,7 @@ public abstract class BasicRestServlet extends RestServlet implements BasicUnive
@Override /* BasicRestOperations */
public HttpResource getFavIcon() {
- String favIcon = getContext().getConfig().getString("REST/favicon", "images/juneau.png");
+ String favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
return getHtdoc(favIcon, null);
}
diff --git a/juneau-sc/juneau-sc-server/src/main/java/org/apache/juneau/server/config/repository/GetConfiguration.java b/juneau-sc/juneau-sc-server/src/main/java/org/apache/juneau/server/config/repository/GetConfiguration.java
index e01be54..0993724 100644
--- a/juneau-sc/juneau-sc-server/src/main/java/org/apache/juneau/server/config/repository/GetConfiguration.java
+++ b/juneau-sc/juneau-sc-server/src/main/java/org/apache/juneau/server/config/repository/GetConfiguration.java
@@ -42,9 +42,9 @@ public class GetConfiguration implements Command, GetValue<Map<String, ConfigIte
Config config = Config.create().name("juneau-server-config.cfg").build();
- String pathStr = config.getString("GitServer/pathLocal");
+ String pathStr = config.get("GitServer/pathLocal").orElse(null);
- String git = config.get("GitServer/gitRemote");
+ String git = config.get("GitServer/gitRemote").orElse(null);
GitControl gitControl = new GitControl(pathStr, git);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigImportsTest.java b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigImportsTest.java
index 5f13c20..2a1fea4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigImportsTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigImportsTest.java
@@ -40,7 +40,7 @@ public class ConfigImportsTest {
.create("B")
.store(ms)
.build();
- assertEquals("1", c.getString("x"));
+ assertEquals("1", c.get("x").get());
c.set("x", "2");
c.commit();
@@ -55,8 +55,8 @@ public class ConfigImportsTest {
ms.write("A2", "", "y=2");
ms.write("B", "", "<A1>\n<A2>");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("x"));
- assertEquals("2", c.getString("y"));
+ assertEquals("1", c.get("x").get());
+ assertEquals("2", c.get("y").get());
c.set("x", "3");
c.set("y", "4");
@@ -73,8 +73,8 @@ public class ConfigImportsTest {
ms.write("A2", "", "<A1>\ny=2");
ms.write("B", "", "<A2>");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("x"));
- assertEquals("2", c.getString("y"));
+ assertEquals("1", c.get("x").get());
+ assertEquals("2", c.get("y").get());
c.set("x", "3");
c.set("y", "4");
@@ -99,7 +99,7 @@ public class ConfigImportsTest {
ConfigMemoryStore ms = ConfigMemoryStore.create().build();
ms.write("B", "", "<A>\nx=1");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("x"));
+ assertEquals("1", c.get("x").get());
}
@Test
@@ -108,10 +108,10 @@ public class ConfigImportsTest {
ms.write("A", "", "x=1");
ms.write("B", "", "<A>");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("x"));
+ assertEquals("1", c.get("x").get());
c.set("x", "2");
- assertEquals("2", c.getString("x"));
- assertEquals("1", Config.create("A").store(ms).build().getString("x"));
+ assertEquals("2", c.get("x").get());
+ assertEquals("1", Config.create("A").store(ms).build().get("x").get());
}
@Test
@@ -120,8 +120,8 @@ public class ConfigImportsTest {
ms.write("A", "", "x=1\n[A]\na1=1");
ms.write("B", "", "<A>\n[A]\na2=2");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("A/a1"));
- assertEquals("2", c.getString("A/a2"));
+ assertEquals("1", c.get("A/a1").get());
+ assertEquals("2", c.get("A/a2").get());
}
@Test
@@ -130,8 +130,8 @@ public class ConfigImportsTest {
ms.write("A", "", "x=1\n[A]\na1=1");
ms.write("B", "", "[A]\na2=2\n<A>");
Config c = Config.create("B").store(ms).build();
- assertEquals("1", c.getString("A/a1"));
- assertEquals("2", c.getString("A/a2"));
+ assertEquals("1", c.get("A/a1").get());
+ assertEquals("2", c.get("A/a2").get());
}
@Test
@@ -140,7 +140,7 @@ public class ConfigImportsTest {
ms.write("A", "", "x=1\n[A]\na1=1");
ms.write("B", "", "<A>\n[A]\na1=2");
Config c = Config.create("B").store(ms).build();
- assertEquals("2", c.getString("A/a1"));
+ assertEquals("2", c.get("A/a1").get());
}
//-----------------------------------------------------------------------------------------------------------------
@@ -207,8 +207,8 @@ public class ConfigImportsTest {
assertEquals(1, l.getEvents().size());
assertEquals("2", l.getNewValue("A", "a1"));
- assertEquals("2", cb.get("A/a1"));
- assertEquals("2", cb.get("B/b1"));
+ assertEquals("2", cb.get("A/a1").get());
+ assertEquals("2", cb.get("B/b1").get());
l.reset();
cb.removeListener(l);
@@ -219,8 +219,8 @@ public class ConfigImportsTest {
assertFalse(l.isTriggered());
- assertEquals("3", cb.get("A/a1"));
- assertEquals("2", cb.get("B/b1"));
+ assertEquals("3", cb.get("A/a1").get());
+ assertEquals("2", cb.get("B/b1").get());
}
@Test
@@ -252,9 +252,9 @@ public class ConfigImportsTest {
assertEquals(1, l.getEvents().size());
assertEquals("2", l.getNewValue("A", "a1"));
- assertEquals("2", cc.get("A/a1"));
- assertEquals("2", cc.get("B/b1"));
- assertEquals("3", cc.get("C/c1"));
+ assertEquals("2", cc.get("A/a1").get());
+ assertEquals("2", cc.get("B/b1").get());
+ assertEquals("3", cc.get("C/c1").get());
l.reset();
cc.removeListener(l);
@@ -266,9 +266,9 @@ public class ConfigImportsTest {
assertFalse(l.isTriggered());
- assertEquals("3", cc.get("A/a1"));
- assertEquals("2", cc.get("B/b1"));
- assertEquals("3", cc.get("C/c1"));
+ assertEquals("3", cc.get("A/a1").get());
+ assertEquals("2", cc.get("B/b1").get());
+ assertEquals("3", cc.get("C/c1").get());
}
@Test
@@ -293,8 +293,8 @@ public class ConfigImportsTest {
assertEquals(1, l.getEvents().size());
assertEquals("2", l.getNewValue("A", "a1"));
- assertEquals("2", cb.get("A/a1"));
- assertEquals("2", cb.get("A/b1"));
+ assertEquals("2", cb.get("A/a1").get());
+ assertEquals("2", cb.get("A/b1").get());
l.reset();
cb.removeListener(l);
@@ -305,8 +305,8 @@ public class ConfigImportsTest {
assertFalse(l.isTriggered());
- assertEquals("3", cb.get("A/a1"));
- assertEquals("2", cb.get("A/b1"));
+ assertEquals("3", cb.get("A/a1").get());
+ assertEquals("2", cb.get("A/b1").get());
}
@Test
@@ -328,7 +328,7 @@ public class ConfigImportsTest {
ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=3");
assertFalse(l.isTriggered());
- assertEquals("2", cb.get("A/a1"));
+ assertEquals("2", cb.get("A/a1").get());
}
@Test
@@ -353,7 +353,7 @@ public class ConfigImportsTest {
ms.write("A", "x=1\n[A]\na1=1", "x=1\n[A]\na1=4");
assertFalse(l.isTriggered());
- assertEquals("3", cc.get("A/a1"));
+ assertEquals("3", cc.get("A/a1").get());
}
//-----------------------------------------------------------------------------------------------------------------
@@ -385,8 +385,8 @@ public class ConfigImportsTest {
assertEquals(2, l.getEvents().size()); // Should contain [SET(y = 1), SET(A/a1 = 1)]
assertEquals("1", l.getNewValue("A", "a1"));
- assertEquals("1", cb.get("A/a1"));
- assertEquals("2", cb.get("B/b1"));
+ assertEquals("1", cb.get("A/a1").get());
+ assertEquals("2", cb.get("B/b1").get());
assertEquals(2, ca.getConfigMap().getListeners().size());
assertEquals(1, cb.getConfigMap().getListeners().size());
@@ -399,8 +399,8 @@ public class ConfigImportsTest {
assertEquals(2, l.getEvents().size()); // Should contain [REMOVE_ENTRY(y), REMOVE_ENTRY(A/a1)]
assertEquals(null, l.getNewValue("A", "a1"));
- assertNull(cb.get("A/a1"));
- assertEquals("2", cb.get("B/b1"));
+ assertNull(cb.get("A/a1").orElse(null));
+ assertEquals("2", cb.get("B/b1").get());
l.reset();
cb.removeListener(l);
@@ -411,7 +411,7 @@ public class ConfigImportsTest {
assertFalse(l.isTriggered());
- assertEquals("1", cb.get("A/a1"));
- assertEquals("2", cb.get("B/b1"));
+ assertEquals("1", cb.get("A/a1").get());
+ assertEquals("2", cb.get("B/b1").get());
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
index 6fb6e5f..f7ad992 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigInterfaceTest.java
@@ -43,21 +43,21 @@ public class ConfigInterfaceTest {
public void testString() throws Exception {
proxy.setString("foo");
assertEquals("foo", proxy.getString());
- assertEquals("foo", cf.get("A/string"));
+ assertEquals("foo", cf.get("A/string").get());
}
@Test
public void testInt() throws Exception {
proxy.setInt(1);
assertEquals(1, proxy.getInt());
- assertEquals("1", cf.get("A/int"));
+ assertEquals("1", cf.get("A/int").get());
}
@Test
public void testInteger() throws Exception {
proxy.setInteger(2);
assertEquals(2, proxy.getInteger().intValue());
- assertEquals("2", cf.get("A/integer"));
+ assertEquals("2", cf.get("A/integer").get());
assertObject(proxy.getInteger()).isType(Integer.class);
}
@@ -65,14 +65,14 @@ public class ConfigInterfaceTest {
public void testBoolean() throws Exception {
proxy.setBoolean(true);
assertEquals(true, proxy.isBoolean());
- assertEquals("true", cf.get("A/boolean"));
+ assertEquals("true", cf.get("A/boolean").get());
}
@Test
public void testBooleanObject() throws Exception {
proxy.setBooleanObject(true);
assertEquals(true, proxy.getBooleanObject().booleanValue());
- assertEquals("true", cf.get("A/booleanObject"));
+ assertEquals("true", cf.get("A/booleanObject").get());
assertObject(proxy.getBooleanObject()).isType(Boolean.class);
}
@@ -80,21 +80,21 @@ public class ConfigInterfaceTest {
public void testFloat() throws Exception {
proxy.setFloat(1f);
assertTrue(1f == proxy.getFloat());
- assertEquals("1.0", cf.get("A/float"));
+ assertEquals("1.0", cf.get("A/float").get());
}
@Test
public void testFloatObject() throws Exception {
proxy.setFloatObject(1f);
assertTrue(1f == proxy.getFloatObject().floatValue());
- assertEquals("1.0", cf.get("A/floatObject"));
+ assertEquals("1.0", cf.get("A/floatObject").get());
assertObject(proxy.getFloatObject()).isType(Float.class);
}
@Test
public void testInt3dArray() throws Exception {
proxy.setInt3dArray(new int[][][]{{{1,2},null},null});
- assertEquals("[[[1,2],null],null]", cf.get("A/int3dArray"));
+ assertEquals("[[[1,2],null],null]", cf.get("A/int3dArray").get());
assertObject(proxy.getInt3dArray()).asJson().is("[[[1,2],null],null]");
assertObject(proxy.getInt3dArray()).isType(int[][][].class);
}
@@ -103,7 +103,7 @@ public class ConfigInterfaceTest {
public void testInteger3dArray() throws Exception {
proxy.setInteger3dArray(new Integer[][][]{{{1,null},null},null});
assertObject(proxy.getInteger3dArray()).asJson().is("[[[1,null],null],null]");
- assertEquals("[[[1,null],null],null]", cf.get("A/integer3dArray"));
+ assertEquals("[[[1,null],null],null]", cf.get("A/integer3dArray").get());
assertObject(proxy.getInteger3dArray()[0][0][0]).isType(Integer.class);
}
@@ -111,14 +111,14 @@ public class ConfigInterfaceTest {
public void testString3dArray() throws Exception {
proxy.setString3dArray(new String[][][]{{{"foo",null},null},null});
assertObject(proxy.getString3dArray()).asJson().is("[[['foo',null],null],null]");
- assertEquals("[[['foo',null],null],null]", cf.get("A/string3dArray"));
+ assertEquals("[[['foo',null],null],null]", cf.get("A/string3dArray").get());
}
@Test
public void testIntegerList() throws Exception {
proxy.setIntegerList(AList.of(1,null));
assertObject(proxy.getIntegerList()).asJson().is("[1,null]");
- assertEquals("[1,null]", cf.get("A/integerList"));
+ assertEquals("[1,null]", cf.get("A/integerList").get());
assertObject(proxy.getIntegerList().get(0)).isType(Integer.class);
}
@@ -126,7 +126,7 @@ public class ConfigInterfaceTest {
public void testInteger3dList() throws Exception {
proxy.setInteger3dList(AList.of(AList.of(AList.of(1,null),null),null));
assertObject(proxy.getInteger3dList()).asJson().is("[[[1,null],null],null]");
- assertEquals("[[[1,null],null],null]", cf.get("A/integer3dList"));
+ assertEquals("[[[1,null],null],null]", cf.get("A/integer3dList").get());
assertObject(proxy.getInteger3dList().get(0).get(0).get(0)).isType(Integer.class);
}
@@ -134,7 +134,7 @@ public class ConfigInterfaceTest {
public void testInteger1d3dList() throws Exception {
proxy.setInteger1d3dList(AList.of(new Integer[][][]{{{1,null},null},null},null));
assertObject(proxy.getInteger1d3dList()).asJson().is("[[[[1,null],null],null],null]");
- assertEquals("[[[[1,null],null],null],null]", cf.get("A/integer1d3dList"));
+ assertEquals("[[[[1,null],null],null],null]", cf.get("A/integer1d3dList").get());
assertObject(proxy.getInteger1d3dList().get(0)[0][0][0]).isType(Integer.class);
}
@@ -142,7 +142,7 @@ public class ConfigInterfaceTest {
public void testInt1d3dList() throws Exception {
proxy.setInt1d3dList(AList.of(new int[][][]{{{1,2},null},null},null));
assertObject(proxy.getInt1d3dList()).asJson().is("[[[[1,2],null],null],null]");
- assertEquals("[[[[1,2],null],null],null]", cf.get("A/int1d3dList"));
+ assertEquals("[[[[1,2],null],null],null]", cf.get("A/int1d3dList").get());
assertObject(proxy.getInt1d3dList().get(0)).isType(int[][][].class);
}
@@ -150,7 +150,7 @@ public class ConfigInterfaceTest {
public void testStringList() throws Exception {
proxy.setStringList(Arrays.asList("foo","bar",null));
assertObject(proxy.getStringList()).asJson().is("['foo','bar',null]");
- assertEquals("['foo','bar',null]", cf.get("A/stringList"));
+ assertEquals("['foo','bar',null]", cf.get("A/stringList").get());
}
// Beans
@@ -159,7 +159,7 @@ public class ConfigInterfaceTest {
public void testBean() throws Exception {
proxy.setBean(ABean.get());
assertObject(proxy.getBean()).asJson().is("{a:1,b:'foo'}");
- assertEquals("{a:1,b:'foo'}", cf.get("A/bean"));
+ assertEquals("{a:1,b:'foo'}", cf.get("A/bean").get());
assertObject(proxy.getBean()).isType(ABean.class);
}
@@ -167,7 +167,7 @@ public class ConfigInterfaceTest {
public void testBean3dArray() throws Exception {
proxy.setBean3dArray(new ABean[][][]{{{ABean.get(),null},null},null});
assertObject(proxy.getBean3dArray()).asJson().is("[[[{a:1,b:'foo'},null],null],null]");
- assertEquals("[[[{a:1,b:'foo'},null],null],null]", cf.get("A/bean3dArray"));
+ assertEquals("[[[{a:1,b:'foo'},null],null],null]", cf.get("A/bean3dArray").get());
assertObject(proxy.getBean3dArray()[0][0][0]).isType(ABean.class);
}
@@ -175,7 +175,7 @@ public class ConfigInterfaceTest {
public void testBeanList() throws Exception {
proxy.setBeanList(Arrays.asList(ABean.get()));
assertObject(proxy.getBeanList()).asJson().is("[{a:1,b:'foo'}]");
- assertEquals("[{a:1,b:'foo'}]", cf.get("A/beanList"));
+ assertEquals("[{a:1,b:'foo'}]", cf.get("A/beanList").get());
assertObject(proxy.getBeanList().get(0)).isType(ABean.class);
}
@@ -183,7 +183,7 @@ public class ConfigInterfaceTest {
public void testBean1d3dList() throws Exception {
proxy.setBean1d3dList(AList.of(new ABean[][][]{{{ABean.get(),null},null},null},null));
assertObject(proxy.getBean1d3dList()).asJson().is("[[[[{a:1,b:'foo'},null],null],null],null]");
- assertEquals("[[[[{a:1,b:'foo'},null],null],null],null]", cf.get("A/bean1d3dList"));
+ assertEquals("[[[[{a:1,b:'foo'},null],null],null],null]", cf.get("A/bean1d3dList").get());
assertObject(proxy.getBean1d3dList().get(0)[0][0][0]).isType(ABean.class);
}
@@ -191,7 +191,7 @@ public class ConfigInterfaceTest {
public void testBeanMap() throws Exception {
proxy.setBeanMap(AMap.of("foo",ABean.get()));
assertObject(proxy.getBeanMap()).asJson().is("{foo:{a:1,b:'foo'}}");
- assertEquals("{foo:{a:1,b:'foo'}}", cf.get("A/beanMap"));
+ assertEquals("{foo:{a:1,b:'foo'}}", cf.get("A/beanMap").get());
assertObject(proxy.getBeanMap().get("foo")).isType(ABean.class);
}
@@ -199,7 +199,7 @@ public class ConfigInterfaceTest {
public void testBeanListMap() throws Exception {
proxy.setBeanListMap(AMap.of("foo",Arrays.asList(ABean.get())));
assertObject(proxy.getBeanListMap()).asJson().is("{foo:[{a:1,b:'foo'}]}");
- assertEquals("{foo:[{a:1,b:'foo'}]}", cf.get("A/beanListMap"));
+ assertEquals("{foo:[{a:1,b:'foo'}]}", cf.get("A/beanListMap").get());
assertObject(proxy.getBeanListMap().get("foo").get(0)).isType(ABean.class);
}
@@ -207,7 +207,7 @@ public class ConfigInterfaceTest {
public void testBean1d3dListMap() throws Exception {
proxy.setBean1d3dListMap(AMap.of("foo",AList.of(new ABean[][][]{{{ABean.get(),null},null},null},null)));
assertObject(proxy.getBean1d3dListMap()).asJson().is("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}");
- assertEquals("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}", cf.get("A/bean1d3dListMap"));
+ assertEquals("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}", cf.get("A/bean1d3dListMap").get());
assertObject(proxy.getBean1d3dListMap().get("foo").get(0)[0][0][0]).isType(ABean.class);
}
@@ -215,7 +215,7 @@ public class ConfigInterfaceTest {
public void testBeanListMapIntegerKeys() throws Exception {
proxy.setBeanListMapIntegerKeys(AMap.of(1,Arrays.asList(ABean.get())));
assertObject(proxy.getBeanListMapIntegerKeys()).asJson().is("{'1':[{a:1,b:'foo'}]}");
- assertEquals("{'1':[{a:1,b:'foo'}]}", cf.get("A/beanListMapIntegerKeys"));
+ assertEquals("{'1':[{a:1,b:'foo'}]}", cf.get("A/beanListMapIntegerKeys").get());
assertObject(proxy.getBeanListMapIntegerKeys().get(1).get(0)).isType(ABean.class);
}
@@ -225,7 +225,7 @@ public class ConfigInterfaceTest {
public void testTypedBean() throws Exception {
proxy.setTypedBean(TypedBeanImpl.get());
assertObject(proxy.getTypedBean()).asJson().is("{a:1,b:'foo'}");
- assertEquals("{_type:'TypedBeanImpl',a:1,b:'foo'}", cf.get("A/typedBean"));
+ assertEquals("{_type:'TypedBeanImpl',a:1,b:'foo'}", cf.get("A/typedBean").get());
assertObject(proxy.getTypedBean()).isType(TypedBeanImpl.class);
}
@@ -233,7 +233,7 @@ public class ConfigInterfaceTest {
public void testTypedBean3dArray() throws Exception {
proxy.setTypedBean3dArray(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null});
assertObject(proxy.getTypedBean3dArray()).asJson().is("[[[{a:1,b:'foo'},null],null],null]");
- assertEquals("[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null]", cf.get("A/typedBean3dArray"));
+ assertEquals("[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null]", cf.get("A/typedBean3dArray").get());
assertObject(proxy.getTypedBean3dArray()[0][0][0]).isType(TypedBeanImpl.class);
}
@@ -241,7 +241,7 @@ public class ConfigInterfaceTest {
public void testTypedBeanList() throws Exception {
proxy.setTypedBeanList(Arrays.asList((TypedBean)TypedBeanImpl.get()));
assertObject(proxy.getTypedBeanList()).asJson().is("[{a:1,b:'foo'}]");
- assertEquals("[{_type:'TypedBeanImpl',a:1,b:'foo'}]", cf.get("A/typedBeanList"));
+ assertEquals("[{_type:'TypedBeanImpl',a:1,b:'foo'}]", cf.get("A/typedBeanList").get());
assertObject(proxy.getTypedBeanList().get(0)).isType(TypedBeanImpl.class);
}
@@ -249,7 +249,7 @@ public class ConfigInterfaceTest {
public void testTypedBean1d3dList() throws Exception {
proxy.setTypedBean1d3dList(AList.of(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null));
assertObject(proxy.getTypedBean1d3dList()).asJson().is("[[[[{a:1,b:'foo'},null],null],null],null]");
- assertEquals("[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]", cf.get("A/typedBean1d3dList"));
+ assertEquals("[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]", cf.get("A/typedBean1d3dList").get());
assertObject(proxy.getTypedBean1d3dList().get(0)[0][0][0]).isType(TypedBeanImpl.class);
}
@@ -257,7 +257,7 @@ public class ConfigInterfaceTest {
public void testTypedBeanMap() throws Exception {
proxy.setTypedBeanMap(AMap.of("foo",TypedBeanImpl.get()));
assertObject(proxy.getTypedBeanMap()).asJson().is("{foo:{a:1,b:'foo'}}");
- assertEquals("{foo:{_type:'TypedBeanImpl',a:1,b:'foo'}}", cf.get("A/typedBeanMap"));
+ assertEquals("{foo:{_type:'TypedBeanImpl',a:1,b:'foo'}}", cf.get("A/typedBeanMap").get());
assertObject(proxy.getTypedBeanMap().get("foo")).isType(TypedBeanImpl.class);
}
@@ -265,7 +265,7 @@ public class ConfigInterfaceTest {
public void testTypedBeanListMap() throws Exception {
proxy.setTypedBeanListMap(AMap.of("foo",Arrays.asList((TypedBean)TypedBeanImpl.get())));
assertObject(proxy.getTypedBeanListMap()).asJson().is("{foo:[{a:1,b:'foo'}]}");
- assertEquals("{foo:[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMap"));
+ assertEquals("{foo:[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMap").get());
assertObject(proxy.getTypedBeanListMap().get("foo").get(0)).isType(TypedBeanImpl.class);
}
@@ -273,7 +273,7 @@ public class ConfigInterfaceTest {
public void testTypedBean1d3dListMap() throws Exception {
proxy.setTypedBean1d3dListMap(AMap.of("foo",AList.of(new TypedBean[][][]{{{TypedBeanImpl.get(),null},null},null},null)));
assertObject(proxy.getTypedBean1d3dListMap()).asJson().is("{foo:[[[[{a:1,b:'foo'},null],null],null],null]}");
- assertEquals("{foo:[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]}", cf.get("A/typedBean1d3dListMap"));
+ assertEquals("{foo:[[[[{_type:'TypedBeanImpl',a:1,b:'foo'},null],null],null],null]}", cf.get("A/typedBean1d3dListMap").get());
assertObject(proxy.getTypedBean1d3dListMap().get("foo").get(0)[0][0][0]).isType(TypedBeanImpl.class);
}
@@ -281,7 +281,7 @@ public class ConfigInterfaceTest {
public void testTypedBeanListMapIntegerKeys() throws Exception {
proxy.setTypedBeanListMapIntegerKeys(AMap.of(1,Arrays.asList((TypedBean)TypedBeanImpl.get())));
assertObject(proxy.getTypedBeanListMapIntegerKeys()).asJson().is("{'1':[{a:1,b:'foo'}]}");
- assertEquals("{'1':[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMapIntegerKeys"));
+ assertEquals("{'1':[{_type:'TypedBeanImpl',a:1,b:'foo'}]}", cf.get("A/typedBeanListMapIntegerKeys").get());
assertObject(proxy.getTypedBeanListMapIntegerKeys().get(1).get(0)).isType(TypedBeanImpl.class);
}
@@ -291,7 +291,7 @@ public class ConfigInterfaceTest {
public void testSwappedObject() throws Exception {
proxy.setSwappedObject(new SwappedObject());
assertObject(proxy.getSwappedObject()).asJson().is("'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'");
- assertEquals("swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/", cf.get("A/swappedObject"));
+ assertEquals("swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/", cf.get("A/swappedObject").get());
assertObject(proxy.getSwappedObject()).isType(SwappedObject.class);
}
@@ -299,7 +299,7 @@ public class ConfigInterfaceTest {
public void testSwappedObject3dArray() throws Exception {
proxy.setSwappedObject3dArray(new SwappedObject[][][]{{{new SwappedObject(),null},null},null});
assertObject(proxy.getSwappedObject3dArray()).asJson().is("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]");
- assertEquals("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]", cf.get("A/swappedObject3dArray"));
+ assertEquals("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]", cf.get("A/swappedObject3dArray").get());
assertObject(proxy.getSwappedObject3dArray()[0][0][0]).isType(SwappedObject.class);
}
@@ -307,7 +307,7 @@ public class ConfigInterfaceTest {
public void testSwappedObjectMap() throws Exception {
proxy.setSwappedObjectMap(AMap.of(new SwappedObject(), new SwappedObject()));
assertObject(proxy.getSwappedObjectMap()).asJson().is("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}");
- assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}", cf.get("A/swappedObjectMap"));
+ assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}", cf.get("A/swappedObjectMap").get());
assertObject(proxy.getSwappedObjectMap().keySet().iterator().next()).isType(SwappedObject.class);
assertObject(proxy.getSwappedObjectMap().values().iterator().next()).isType(SwappedObject.class);
}
@@ -316,7 +316,7 @@ public class ConfigInterfaceTest {
public void testSwappedObject3dMap() throws Exception {
proxy.setSwappedObject3dMap(AMap.of(new SwappedObject(), new SwappedObject[][][]{{{new SwappedObject(),null},null},null}));
assertObject(proxy.getSwappedObject3dMap()).asJson().is("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}");
- assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}", cf.get("A/swappedObject3dMap"));
+ assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}", cf.get("A/swappedObject3dMap").get());
assertObject(proxy.getSwappedObject3dMap().keySet().iterator().next()).isType(SwappedObject.class);
assertObject(proxy.getSwappedObject3dMap().values().iterator().next()[0][0][0]).isType(SwappedObject.class);
}
@@ -327,7 +327,7 @@ public class ConfigInterfaceTest {
public void testImplicitSwappedObject() throws Exception {
proxy.setImplicitSwappedObject(new ImplicitSwappedObject());
assertObject(proxy.getImplicitSwappedObject()).asJson().is("'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'");
- assertEquals("swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/", cf.get("A/implicitSwappedObject"));
+ assertEquals("swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/", cf.get("A/implicitSwappedObject").get());
assertObject(proxy.getImplicitSwappedObject()).isType(ImplicitSwappedObject.class);
}
@@ -335,7 +335,7 @@ public class ConfigInterfaceTest {
public void testImplicitSwappedObject3dArray() throws Exception {
proxy.setImplicitSwappedObject3dArray(new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null});
assertObject(proxy.getImplicitSwappedObject3dArray()).asJson().is("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]");
- assertEquals("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]", cf.get("A/implicitSwappedObject3dArray"));
+ assertEquals("[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]", cf.get("A/implicitSwappedObject3dArray").get());
assertObject(proxy.getImplicitSwappedObject3dArray()[0][0][0]).isType(ImplicitSwappedObject.class);
}
@@ -343,7 +343,7 @@ public class ConfigInterfaceTest {
public void testImplicitSwappedObjectMap() throws Exception {
proxy.setImplicitSwappedObjectMap(AMap.of(new ImplicitSwappedObject(), new ImplicitSwappedObject()));
assertObject(proxy.getImplicitSwappedObjectMap()).asJson().is("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}");
- assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}", cf.get("A/implicitSwappedObjectMap"));
+ assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/'}", cf.get("A/implicitSwappedObjectMap").get());
assertObject(proxy.getImplicitSwappedObjectMap().keySet().iterator().next()).isType(ImplicitSwappedObject.class);
assertObject(proxy.getImplicitSwappedObjectMap().values().iterator().next()).isType(ImplicitSwappedObject.class);
}
@@ -352,7 +352,7 @@ public class ConfigInterfaceTest {
public void testImplicitSwappedObject3dMap() throws Exception {
proxy.setImplicitSwappedObject3dMap(AMap.of(new ImplicitSwappedObject(), new ImplicitSwappedObject[][][]{{{new ImplicitSwappedObject(),null},null},null}));
assertObject(proxy.getImplicitSwappedObject3dMap()).asJson().is("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}");
- assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}", cf.get("A/implicitSwappedObject3dMap"));
+ assertEquals("{'swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/':[[['swap-~!@#$%^&*()_+`-={}[]|:;\"<,>.?/',null],null],null]}", cf.get("A/implicitSwappedObject3dMap").get());
assertObject(proxy.getImplicitSwappedObject3dMap().keySet().iterator().next()).isType(ImplicitSwappedObject.class);
assertObject(proxy.getImplicitSwappedObject3dMap().values().iterator().next()[0][0][0]).isType(ImplicitSwappedObject.class);
}
@@ -363,7 +363,7 @@ public class ConfigInterfaceTest {
public void testEnum() throws Exception {
proxy.setEnum(TestEnum.TWO);
assertObject(proxy.getEnum()).asJson().is("'TWO'");
- assertEquals("TWO", cf.get("A/enum"));
+ assertEquals("TWO", cf.get("A/enum").get());
assertObject(proxy.getEnum()).isType(TestEnum.class);
}
@@ -371,7 +371,7 @@ public class ConfigInterfaceTest {
public void testEnum3d() throws Exception {
proxy.setEnum3d(new TestEnum[][][]{{{TestEnum.TWO,null},null},null});
assertObject(proxy.getEnum3d()).asJson().is("[[['TWO',null],null],null]");
- assertEquals("[[['TWO',null],null],null]", cf.get("A/enum3d"));
+ assertEquals("[[['TWO',null],null],null]", cf.get("A/enum3d").get());
assertObject(proxy.getEnum3d()[0][0][0]).isType(TestEnum.class);
}
@@ -379,7 +379,7 @@ public class ConfigInterfaceTest {
public void testEnumList() throws Exception {
proxy.setEnumList(AList.of(TestEnum.TWO,null));
assertObject(proxy.getEnumList()).asJson().is("['TWO',null]");
- assertEquals("['TWO',null]", cf.get("A/enumList"));
+ assertEquals("['TWO',null]", cf.get("A/enumList").get());
assertObject(proxy.getEnumList().get(0)).isType(TestEnum.class);
}
@@ -387,7 +387,7 @@ public class ConfigInterfaceTest {
public void testEnum3dList() throws Exception {
proxy.setEnum3dList(AList.of(AList.of(AList.of(TestEnum.TWO,null),null),null));
assertObject(proxy.getEnum3dList()).asJson().is("[[['TWO',null],null],null]");
- assertEquals("[[['TWO',null],null],null]", cf.get("A/enum3dList"));
+ assertEquals("[[['TWO',null],null],null]", cf.get("A/enum3dList").get());
assertObject(proxy.getEnum3dList().get(0).get(0).get(0)).isType(TestEnum.class);
}
@@ -395,7 +395,7 @@ public class ConfigInterfaceTest {
public void testEnum1d3dList() throws Exception {
proxy.setEnum1d3dList(AList.of(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null));
assertObject(proxy.getEnum1d3dList()).asJson().is("[[[['TWO',null],null],null],null]");
- assertEquals("[[[['TWO',null],null],null],null]", cf.get("A/enum1d3dList"));
+ assertEquals("[[[['TWO',null],null],null],null]", cf.get("A/enum1d3dList").get());
assertObject(proxy.getEnum1d3dList().get(0)[0][0][0]).isType(TestEnum.class);
}
@@ -403,7 +403,7 @@ public class ConfigInterfaceTest {
public void testEnumMap() throws Exception {
proxy.setEnumMap(AMap.of(TestEnum.ONE,TestEnum.TWO));
assertObject(proxy.getEnumMap()).asJson().is("{ONE:'TWO'}");
- assertEquals("{ONE:'TWO'}", cf.get("A/enumMap"));
+ assertEquals("{ONE:'TWO'}", cf.get("A/enumMap").get());
assertObject(proxy.getEnumMap().keySet().iterator().next()).isType(TestEnum.class);
assertObject(proxy.getEnumMap().values().iterator().next()).isType(TestEnum.class);
}
@@ -412,7 +412,7 @@ public class ConfigInterfaceTest {
public void testEnum3dArrayMap() throws Exception {
proxy.setEnum3dArrayMap(AMap.of(TestEnum.ONE,new TestEnum[][][]{{{TestEnum.TWO,null},null},null}));
assertObject(proxy.getEnum3dArrayMap()).asJson().is("{ONE:[[['TWO',null],null],null]}");
- assertEquals("{ONE:[[['TWO',null],null],null]}", cf.get("A/enum3dArrayMap"));
+ assertEquals("{ONE:[[['TWO',null],null],null]}", cf.get("A/enum3dArrayMap").get());
assertObject(proxy.getEnum3dArrayMap().keySet().iterator().next()).isType(TestEnum.class);
assertObject(proxy.getEnum3dArrayMap().values().iterator().next()[0][0][0]).isType(TestEnum.class);
}
@@ -421,7 +421,7 @@ public class ConfigInterfaceTest {
public void testEnum1d3dListMap() throws Exception {
proxy.setEnum1d3dListMap(AMap.of(TestEnum.ONE,AList.of(new TestEnum[][][]{{{TestEnum.TWO,null},null},null},null)));
assertObject(proxy.getEnum1d3dListMap()).asJson().is("{ONE:[[[['TWO',null],null],null],null]}");
- assertEquals("{ONE:[[[['TWO',null],null],null],null]}", cf.get("A/enum1d3dListMap"));
+ assertEquals("{ONE:[[[['TWO',null],null],null],null]}", cf.get("A/enum1d3dListMap").get());
assertObject(proxy.getEnum1d3dListMap().keySet().iterator().next()).isType(TestEnum.class);
assertObject(proxy.getEnum1d3dListMap().values().iterator().next().get(0)[0][0][0]).isType(TestEnum.class);
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigTest.java b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigTest.java
index 78baf20..f96bc98 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/config/ConfigTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/config/ConfigTest.java
@@ -47,12 +47,12 @@ public class ConfigTest {
public void get() throws Exception {
Config c = init("a=1", "[S]", "b=2");
- assertEquals("1", c.get("a"));
- assertEquals("1", c.get("a"));
- assertEquals("2", c.get("S/b"));
- assertNull(c.get("b"));
- assertNull(c.get("S/c"));
- assertNull(c.get("T/d"));
+ assertEquals("1", c.get("a").get());
+ assertEquals("1", c.get("a").get());
+ assertEquals("2", c.get("S/b").get());
+ assertNull(c.get("b").orElse(null));
+ assertNull(c.get("S/c").orElse(null));
+ assertNull(c.get("T/d").orElse(null));
assertThrown(()->c.get(null)).message().is("Argument 'key' cannot be null.");
c.close();
}
@@ -71,30 +71,30 @@ public class ConfigTest {
c.set("S/b2", "6");
c.set("T/c1", "7");
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
c.commit();
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
c = cb.build();
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
assertString(c).replaceAll("\\r?\\n", "|").is("a1 = 2|a2 = 3|a3 = 4|[S]|b1 = 5|b2 = 6|[T]|c1 = 7|");
}
@@ -113,30 +113,30 @@ public class ConfigTest {
c.set("S/b2", 6);
c.set("T/c1", 7);
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
c.commit();
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
c = cb.build();
- assertEquals("2", c.get("a1"));
- assertEquals("3", c.get("a2"));
- assertEquals("4", c.get("a3"));
- assertEquals("5", c.get("S/b1"));
- assertEquals("6", c.get("S/b2"));
- assertEquals("7", c.get("T/c1"));
+ assertEquals("2", c.get("a1").get());
+ assertEquals("3", c.get("a2").get());
+ assertEquals("4", c.get("a3").get());
+ assertEquals("5", c.get("S/b1").get());
+ assertEquals("6", c.get("S/b2").get());
+ assertEquals("7", c.get("T/c1").get());
assertString(c).replaceAll("\\r?\\n", "|").is("a1 = 2|a2 = 3|a3 = 4|[S]|b1 = 5|b2 = 6|[T]|c1 = 7|");
}
@@ -156,12 +156,12 @@ public class ConfigTest {
c.set("S/b2", b, UonSerializer.DEFAULT);
c.set("T/c1", b, UonSerializer.DEFAULT);
- assertEquals("(foo=bar)", c.get("a1"));
- assertEquals("(foo=bar)", c.get("a2"));
- assertEquals("(foo=bar)", c.get("a3"));
- assertEquals("(foo=bar)", c.get("S/b1"));
- assertEquals("(foo=bar)", c.get("S/b2"));
- assertEquals("(foo=bar)", c.get("T/c1"));
+ assertEquals("(foo=bar)", c.get("a1").get());
+ assertEquals("(foo=bar)", c.get("a2").get());
+ assertEquals("(foo=bar)", c.get("a3").get());
+ assertEquals("(foo=bar)", c.get("S/b1").get());
+ assertEquals("(foo=bar)", c.get("S/b2").get());
+ assertEquals("(foo=bar)", c.get("T/c1").get());
}
//====================================================================================================
@@ -185,12 +185,12 @@ public class ConfigTest {
c = cb.build();
assertString(c).replaceAll("\\r?\\n", "|").is("#c1|#c2|a1* = {RhMWWFIFVksf} # comment|#c1|#c2|a2* = {RhMWWFIFVksf} # comment|#c1|#c2|a3* = {RhMWWFIFVksf} # comment|[S]|#c1|#c2|b1* = {RhMWWFIFVksf} # comment|#c1|#c2|b2* = {RhMWWFIFVksf} # comment|[T]|#c1|#c2|c1* = {RhMWWFIFVksf} # comment|");
- assertEquals("(foo=bar)", c.get("a1"));
- assertEquals("(foo=bar)", c.get("a2"));
- assertEquals("(foo=bar)", c.get("a3"));
- assertEquals("(foo=bar)", c.get("S/b1"));
- assertEquals("(foo=bar)", c.get("S/b2"));
- assertEquals("(foo=bar)", c.get("T/c1"));
+ assertEquals("(foo=bar)", c.get("a1").get());
+ assertEquals("(foo=bar)", c.get("a2").get());
+ assertEquals("(foo=bar)", c.get("a3").get());
+ assertEquals("(foo=bar)", c.get("S/b1").get());
+ assertEquals("(foo=bar)", c.get("S/b2").get());
+ assertEquals("(foo=bar)", c.get("T/c1").get());
}
//====================================================================================================
@@ -220,13 +220,13 @@ public class ConfigTest {
public void xgetString1() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals("1", c.getString("a1"));
- assertEquals("2", c.getString("a2"));
- assertEquals(null, c.getString("a3"));
- assertEquals("1", c.getString("S/b1"));
- assertEquals("", c.getString("S/b2"));
- assertEquals(null, c.getString("S/b3"));
- assertEquals(null, c.getString("T/c1"));
+ assertEquals("1", c.get("a1").as(String.class).orElse(null));
+ assertEquals("2", c.get("a2").as(String.class).orElse(null));
+ assertEquals(null, c.get("a3").as(String.class).orElse(null));
+ assertEquals("1", c.get("S/b1").as(String.class).orElse(null));
+ assertEquals("", c.get("S/b2").as(String.class).orElse(null));
+ assertEquals(null, c.get("S/b3").as(String.class).orElse(null));
+ assertEquals(null, c.get("T/c1").as(String.class).orElse(null));
}
//====================================================================================================
@@ -235,13 +235,13 @@ public class ConfigTest {
@Test
public void getString2() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals("1", c.getString("a1", "foo"));
- assertEquals("2", c.getString("a2", "foo"));
- assertEquals("foo", c.getString("a3", "foo"));
- assertEquals("1", c.getString("S/b1", "foo"));
- assertEquals("foo", c.getString("S/b2", "foo"));
- assertEquals("foo", c.getString("S/b3", "foo"));
- assertEquals("foo", c.getString("T/c1", "foo"));
+ assertEquals("1", c.get("a1").orElse("foo"));
+ assertEquals("2", c.get("a2").orElse("foo"));
+ assertEquals("foo", c.get("a3").orElse("foo"));
+ assertEquals("1", c.get("S/b1").orElse("foo"));
+ assertEquals("", c.get("S/b2").orElse("foo"));
+ assertEquals("foo", c.get("S/b3").orElse("foo"));
+ assertEquals("foo", c.get("T/c1").orElse("foo"));
}
//====================================================================================================
@@ -250,13 +250,13 @@ public class ConfigTest {
@Test
public void getStringArray1() throws Exception {
Config c = init("a1=1,2", "a2= 2 , 3 ", "[S]", "b1=1", "b2=");
- assertObject(c.getStringArray("a1")).asJson().is("['1','2']");
- assertObject(c.getStringArray("a2")).asJson().is("['2','3']");
- assertObject(c.getStringArray("a3")).asJson().is("[]");
- assertObject(c.getStringArray("S/b1")).asJson().is("['1']");
- assertObject(c.getStringArray("S/b2")).asJson().is("[]");
- assertObject(c.getStringArray("S/b3")).asJson().is("[]");
- assertObject(c.getStringArray("T/c1")).asJson().is("[]");
+ assertObject(c.get("a1").as(String[].class).orElse(null)).asJson().is("['1','2']");
+ assertObject(c.get("a2").as(String[].class).orElse(null)).asJson().is("['2','3']");
+ assertObject(c.get("a3").as(String[].class).orElse(null)).isNull();
+ assertObject(c.get("S/b1").as(String[].class).orElse(null)).asJson().is("['1']");
+ assertObject(c.get("S/b2").as(String[].class).orElse(null)).asJson().is("[]");
+ assertObject(c.get("S/b3").as(String[].class).orElse(null)).isNull();
+ assertObject(c.get("T/c1").as(String[].class).orElse(null)).isNull();
}
//====================================================================================================
@@ -265,13 +265,13 @@ public class ConfigTest {
@Test
public void getStringArray2() throws Exception {
Config c = init("a1=1,2", "a2= 2 , 3 ", "[S]", "b1=1", "b2=");
- assertObject(c.getStringArray("a1", new String[] {"foo"})).asJson().is("['1','2']");
- assertObject(c.getStringArray("a2", new String[] {"foo"})).asJson().is("['2','3']");
- assertObject(c.getStringArray("a3", new String[] {"foo"})).asJson().is("['foo']");
- assertObject(c.getStringArray("S/b1", new String[] {"foo"})).asJson().is("['1']");
- assertObject(c.getStringArray("S/b2", new String[] {"foo"})).asJson().is("['foo']");
- assertObject(c.getStringArray("S/b3", new String[] {"foo"})).asJson().is("['foo']");
- assertObject(c.getStringArray("T/c1", new String[] {"foo"})).asJson().is("['foo']");
+ assertObject(c.get("a1").asStringArray().orElse(new String[] {"foo"})).asJson().is("['1','2']");
+ assertObject(c.get("a2").asStringArray().orElse(new String[] {"foo"})).asJson().is("['2','3']");
+ assertObject(c.get("a3").asStringArray().orElse(new String[] {"foo"})).asJson().is("['foo']");
+ assertObject(c.get("S/b1").asStringArray().orElse(new String[] {"foo"})).asJson().is("['1']");
+ assertObject(c.get("S/b2").asStringArray().orElse(new String[] {"foo"})).asJson().is("[]");
+ assertObject(c.get("S/b3").asStringArray().orElse(new String[] {"foo"})).asJson().is("['foo']");
+ assertObject(c.get("T/c1").asStringArray().orElse(new String[] {"foo"})).asJson().is("['foo']");
}
//====================================================================================================
@@ -280,22 +280,22 @@ public class ConfigTest {
@Test
public void getInt1() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals(1, c.getInt("a1"));
- assertEquals(2, c.getInt("a2"));
- assertEquals(0, c.getInt("a3"));
- assertEquals(1, c.getInt("S/b1"));
- assertEquals(0, c.getInt("S/b2"));
- assertEquals(0, c.getInt("S/b3"));
- assertEquals(0, c.getInt("T/c1"));
+ assertInteger(c.get("a1").asInteger().orElse(0)).is(1);
+ assertInteger(c.get("a2").asInteger().orElse(0)).is(2);
+ assertInteger(c.get("a3").asInteger().orElse(0)).is(0);
+ assertInteger(c.get("S/b1").asInteger().orElse(0)).is(1);
+ assertInteger(c.get("S/b2").asInteger().orElse(0)).is(0);
+ assertInteger(c.get("S/b3").asInteger().orElse(0)).is(0);
+ assertInteger(c.get("T/c1").asInteger().orElse(0)).is(0);
}
@Test
public void getInt1BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=false");
- assertThrown(()->c.getInt("a1")).exists();
- assertThrown(()->c.getInt("a2")).exists();
- assertThrown(()->c.getInt("a3")).exists();
- assertThrown(()->c.getInt("a4")).exists();
+ assertThrown(()->c.get("a1").asInteger().orElse(0)).exists();
+ assertThrown(()->c.get("a2").asInteger().orElse(0)).exists();
+ assertThrown(()->c.get("a3").asInteger().orElse(0)).exists();
+ assertThrown(()->c.get("a4").asInteger().orElse(0)).exists();
}
//====================================================================================================
@@ -304,22 +304,22 @@ public class ConfigTest {
@Test
public void getInt2() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals(1, c.getInt("a1", -1));
- assertEquals(2, c.getInt("a2", -1));
- assertEquals(-1, c.getInt("a3", -1));
- assertEquals(1, c.getInt("S/b1", -1));
- assertEquals(-1, c.getInt("S/b2", -1));
- assertEquals(-1, c.getInt("S/b3", -1));
- assertEquals(-1, c.getInt("T/c1", -1));
+ assertInteger(c.get("a1").asInteger().orElse(-1)).is(1);
+ assertInteger(c.get("a2").asInteger().orElse(-1)).is(2);
+ assertInteger(c.get("a3").asInteger().orElse(-1)).is(-1);
+ assertInteger(c.get("S/b1").asInteger().orElse(-1)).is(1);
+ assertInteger(c.get("S/b2").asInteger().orElse(-1)).is(-1);
+ assertInteger(c.get("S/b3").asInteger().orElse(-1)).is(-1);
+ assertInteger(c.get("T/c1").asInteger().orElse(-1)).is(-1);
}
@Test
public void getInt2BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=false");
- assertThrown(()->c.getInt("a1", -1)).exists();
- assertThrown(()->c.getInt("a2", -1)).exists();
- assertThrown(()->c.getInt("a3", -1)).exists();
- assertThrown(()->c.getInt("a4", -1)).exists();
+ assertThrown(()->c.get("a1").asInteger().orElse(-1)).exists();
+ assertThrown(()->c.get("a2").asInteger().orElse(-1)).exists();
+ assertThrown(()->c.get("a3").asInteger().orElse(-1)).exists();
+ assertThrown(()->c.get("a4").asInteger().orElse(-1)).exists();
}
//====================================================================================================
@@ -328,22 +328,22 @@ public class ConfigTest {
@Test
public void getBoolean1() throws Exception {
Config c = init("a1=true", "a2=false", "[S]", "b1=TRUE", "b2=");
- assertEquals(true, c.getBoolean("a1"));
- assertEquals(false, c.getBoolean("a2"));
- assertEquals(false, c.getBoolean("a3"));
- assertEquals(true, c.getBoolean("S/b1"));
- assertEquals(false, c.getBoolean("S/b2"));
- assertEquals(false, c.getBoolean("S/b3"));
- assertEquals(false, c.getBoolean("T/c1"));
+ assertEquals(true, c.get("a1").asBoolean().orElse(false));
+ assertEquals(false, c.get("a2").asBoolean().orElse(false));
+ assertEquals(false, c.get("a3").asBoolean().orElse(false));
+ assertEquals(true, c.get("S/b1").asBoolean().orElse(false));
+ assertEquals(false, c.get("S/b2").asBoolean().orElse(false));
+ assertEquals(false, c.get("S/b3").asBoolean().orElse(false));
+ assertEquals(false, c.get("T/c1").asBoolean().orElse(false));
}
@Test
public void getBoolean1BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=T");
- assertEquals(false, c.getBoolean("a1"));
- assertEquals(false, c.getBoolean("a2"));
- assertEquals(false, c.getBoolean("a3"));
- assertEquals(false, c.getBoolean("a4"));
+ assertEquals(false, c.get("a1").asBoolean().orElse(false));
+ assertEquals(false, c.get("a2").asBoolean().orElse(false));
+ assertEquals(false, c.get("a3").asBoolean().orElse(false));
+ assertEquals(false, c.get("a4").asBoolean().orElse(false));
}
//====================================================================================================
@@ -352,22 +352,22 @@ public class ConfigTest {
@Test
public void getBoolean2() throws Exception {
Config c = init("a1=true", "a2=false", "[S]", "b1=TRUE", "b2=");
- assertEquals(true, c.getBoolean("a1", true));
- assertEquals(false, c.getBoolean("a2", true));
- assertEquals(true, c.getBoolean("a3", true));
- assertEquals(true, c.getBoolean("S/b1", true));
- assertEquals(true, c.getBoolean("S/b2", true));
- assertEquals(true, c.getBoolean("S/b3", true));
- assertEquals(true, c.getBoolean("T/c1", true));
+ assertEquals(true, c.get("a1").asBoolean().orElse(true));
+ assertEquals(false, c.get("a2").asBoolean().orElse(true));
+ assertEquals(true, c.get("a3").asBoolean().orElse(true));
+ assertEquals(true, c.get("S/b1").asBoolean().orElse(true));
+ assertEquals(true, c.get("S/b2").asBoolean().orElse(true));
+ assertEquals(true, c.get("S/b3").asBoolean().orElse(true));
+ assertEquals(true, c.get("T/c1").asBoolean().orElse(true));
}
@Test
public void getBoolean2BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=T");
- assertEquals(false, c.getBoolean("a1", true));
- assertEquals(false, c.getBoolean("a2", true));
- assertEquals(false, c.getBoolean("a3", true));
- assertEquals(false, c.getBoolean("a4", true));
+ assertEquals(false, c.get("a1").asBoolean().orElse(true));
+ assertEquals(false, c.get("a2").asBoolean().orElse(true));
+ assertEquals(false, c.get("a3").asBoolean().orElse(true));
+ assertEquals(false, c.get("a4").asBoolean().orElse(true));
}
//====================================================================================================
@@ -376,22 +376,22 @@ public class ConfigTest {
@Test
public void getLong1() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals(1l, c.getLong("a1"));
- assertEquals(2l, c.getLong("a2"));
- assertEquals(0l, c.getLong("a3"));
- assertEquals(1l, c.getLong("S/b1"));
- assertEquals(0l, c.getLong("S/b2"));
- assertEquals(0l, c.getLong("S/b3"));
- assertEquals(0l, c.getLong("T/c1"));
+ assertLong(c.get("a1").asLong().orElse(0l)).is(1l);
+ assertLong(c.get("a2").asLong().orElse(0l)).is(2l);
+ assertLong(c.get("a3").asLong().orElse(0l)).is(0l);
+ assertLong(c.get("S/b1").asLong().orElse(0l)).is(1l);
+ assertLong(c.get("S/b2").asLong().orElse(0l)).is(0l);
+ assertLong(c.get("S/b3").asLong().orElse(0l)).is(0l);
+ assertLong(c.get("T/c1").asLong().orElse(0l)).is(0l);
}
@Test
public void getLong1BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=false");
- assertThrown(()->c.getLong("a1")).exists();
- assertThrown(()->c.getLong("a2")).exists();
- assertThrown(()->c.getLong("a3")).exists();
- assertThrown(()->c.getLong("a4")).exists();
+ assertThrown(()->c.get("a1").as(long.class)).exists();
+ assertThrown(()->c.get("a2").as(long.class)).exists();
+ assertThrown(()->c.get("a3").as(long.class)).exists();
+ assertThrown(()->c.get("a4").as(long.class)).exists();
}
//====================================================================================================
@@ -400,23 +400,23 @@ public class ConfigTest {
@Test
public void getLong2() throws Exception {
Config c = init("a1=1", "a2=2", "[S]", "b1=1", "b2=");
- assertEquals(1l, c.getLong("a1", Long.MAX_VALUE));
- assertEquals(2l, c.getLong("a2", Long.MAX_VALUE));
- assertEquals(Long.MAX_VALUE, c.getLong("a3", Long.MAX_VALUE));
- assertEquals(1l, c.getLong("S/b1", Long.MAX_VALUE));
- assertEquals(Long.MAX_VALUE, c.getLong("S/b2", Long.MAX_VALUE));
- assertEquals(Long.MAX_VALUE, c.getLong("S/b3", Long.MAX_VALUE));
- assertEquals(Long.MAX_VALUE, c.getLong("T/c1", Long.MAX_VALUE));
+ assertLong(c.get("a1").asLong().orElse(Long.MAX_VALUE)).is(1l);
+ assertLong(c.get("a2").asLong().orElse(Long.MAX_VALUE)).is(2l);
+ assertLong(c.get("a3").asLong().orElse(Long.MAX_VALUE)).is(Long.MAX_VALUE);
+ assertLong(c.get("S/b1").asLong().orElse(Long.MAX_VALUE)).is(1l);
+ assertLong(c.get("S/b2").asLong().orElse(Long.MAX_VALUE)).is(Long.MAX_VALUE);
+ assertLong(c.get("S/b3").asLong().orElse(Long.MAX_VALUE)).is(Long.MAX_VALUE);
+ assertLong(c.get("T/c1").asLong().orElse(Long.MAX_VALUE)).is(Long.MAX_VALUE);
}
@Test
public void getLong2BadValues() throws Exception {
Config c = init("a1=foo", "a2=2.3", "a3=[1]", "a4=false");
- assertThrown(()->c.getLong("a1", -1l)).isType(NumberFormatException.class);
- assertThrown(()->c.getLong("a2", -1l)).isType(NumberFormatException.class);
- assertThrown(()->c.getLong("a3", -1l)).isType(NumberFormatException.class);
- assertThrown(()->c.getLong("a4", -1l)).isType(NumberFormatException.class);
+ assertThrown(()->c.get("a1").asLong().orElse(-1l)).isType(NumberFormatException.class);
+ assertThrown(()->c.get("a2").asLong().orElse(-1l)).isType(NumberFormatException.class);
+ assertThrown(()->c.get("a3").asLong().orElse(-1l)).isType(NumberFormatException.class);
+ assertThrown(()->c.get("a4").asLong().orElse(-1l)).isType(NumberFormatException.class);
}
//====================================================================================================
@@ -426,10 +426,10 @@ public class ConfigTest {
public void getBytes1() throws Exception {
Config c = init("a1=Zm9v", "a2=Zm", "\t9v", "a3=");
- assertObject(c.getBytes("a1")).asJson().is("[102,111,111]");
- assertObject(c.getBytes("a2")).asJson().is("[102,111,111]");
- assertObject(c.getBytes("a3")).asJson().is("[]");
- assertNull(null, c.getBytes("a4"));
+ assertObject(c.get("a1").as(byte[].class)).asJson().is("[102,111,111]");
+ assertObject(c.get("a2").as(byte[].class)).asJson().is("[102,111,111]");
+ assertObject(c.get("a3").as(byte[].class)).asJson().is("[]");
+ assertNull(null, c.get("a4").to(byte[].class));
}
//====================================================================================================
@@ -439,10 +439,10 @@ public class ConfigTest {
public void getBytes2() throws Exception {
Config c = init("a1=Zm9v", "a2=Zm", "\t9v", "a3=");
- assertObject(c.getBytes("a1", new byte[] {1})).asJson().is("[102,111,111]");
- assertObject(c.getBytes("a2", new byte[] {1})).asJson().is("[102,111,111]");
- assertObject(c.getBytes("a3", new byte[] {1})).asJson().is("[1]");
- assertObject(c.getBytes("a4", new byte[] {1})).asJson().is("[1]");
+ assertObject(c.get("a1").asBytes().orElse(new byte[] {1})).asJson().is("[102,111,111]");
+ assertObject(c.get("a2").asBytes().orElse(new byte[] {1})).asJson().is("[102,111,111]");
+ assertObject(c.get("a3").asBytes().orElse(new byte[] {1})).asJson().is("[]");
+ assertObject(c.get("a4").asBytes().orElse(new byte[] {1})).asJson().is("[1]");
}
//====================================================================================================
@@ -459,29 +459,29 @@ public class ConfigTest {
"\t}"
);
- Map<String,Integer> a1 = c.getObject("a1", Map.class, String.class, Integer.class);
+ Map<String,Integer> a1 = c.get("a1").to(Map.class, String.class, Integer.class);
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- List<Map<String,Integer>> a2a = c.getObject("a2", List.class, Map.class, String.class, Integer.class);
+ List<Map<String,Integer>> a2a = c.get("a2").to(List.class, Map.class, String.class, Integer.class);
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(a2a.get(0).keySet().iterator().next()).isType(String.class);
assertObject(a2a.get(0).values().iterator().next()).isType(Integer.class);
- List<ABean> a2b = c.getObject("a2", List.class, ABean.class);
+ List<ABean> a2b = c.get("a2").to(List.class, ABean.class);
assertObject(a2b).asJson().is("[{foo:'123'}]");
assertObject(a2b.get(0)).isType(ABean.class);
- Map<String,Integer> a3 = c.getObject("a3", Map.class, String.class, Integer.class);
+ Map<String,Integer> a3 = c.get("a3").to(Map.class, String.class, Integer.class);
assertNull(a3);
- Map<String,Integer> a4a = c.getObject("a4", Map.class, String.class, Integer.class);
+ Map<String,Integer> a4a = c.get("a4").to(Map.class, String.class, Integer.class);
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- ABean a4b = c.getObject("a4", ABean.class);
+ ABean a4b = c.get("a4").as(ABean.class).get();
assertObject(a4b).asJson().is("{foo:'123'}");
assertObject(a4b).isType(ABean.class);
}
@@ -500,29 +500,29 @@ public class ConfigTest {
"\t)"
);
- Map<String,Integer> a1 = c.getObject("a1", UonParser.DEFAULT, Map.class, String.class, Integer.class);
+ Map<String,Integer> a1 = c.get("a1").to(UonParser.DEFAULT, Map.class, String.class, Integer.class);
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- List<Map<String,Integer>> a2a = c.getObject("a2", UonParser.DEFAULT, List.class, Map.class, String.class, Integer.class);
+ List<Map<String,Integer>> a2a = c.get("a2").to(UonParser.DEFAULT, List.class, Map.class, String.class, Integer.class);
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(a2a.get(0).keySet().iterator().next()).isType(String.class);
assertObject(a2a.get(0).values().iterator().next()).isType(Integer.class);
- List<ABean> a2b = c.getObject("a2", UonParser.DEFAULT, List.class, ABean.class);
+ List<ABean> a2b = c.get("a2").to(UonParser.DEFAULT, List.class, ABean.class);
assertObject(a2b).asJson().is("[{foo:'123'}]");
assertObject(a2b.get(0)).isType(ABean.class);
- Map<String,Integer> a3 = c.getObject("a3", UonParser.DEFAULT, Map.class, String.class, Integer.class);
+ Map<String,Integer> a3 = c.get("a3").to(UonParser.DEFAULT, Map.class, String.class, Integer.class);
assertNull(a3);
- Map<String,Integer> a4a = c.getObject("a4", UonParser.DEFAULT, Map.class, String.class, Integer.class);
+ Map<String,Integer> a4a = c.get("a4").to(UonParser.DEFAULT, Map.class, String.class, Integer.class);
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- ABean a4b = c.getObject("a4", UonParser.DEFAULT, ABean.class);
+ ABean a4b = c.get("a4").as(UonParser.DEFAULT, ABean.class).get();
assertObject(a4b).asJson().is("{foo:'123'}");
assertObject(a4b).isType(ABean.class);
}
@@ -542,25 +542,25 @@ public class ConfigTest {
"\t}"
);
- Map a1 = c.getObject("a1", Map.class);
+ Map a1 = c.get("a1").as(Map.class).get();
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- List a2a = c.getObject("a2", List.class);
+ List a2a = c.get("a2").as(List.class).get();
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(((Map)a2a.get(0)).keySet().iterator().next()).isType(String.class);
assertObject(((Map)a2a.get(0)).values().iterator().next()).isType(Integer.class);
- Map a3 = c.getObject("a3", Map.class);
+ Map a3 = c.get("a3").as(Map.class).orElse(null);
assertNull(a3);
- Map a4a = c.getObject("a4", Map.class);
+ Map a4a = c.get("a4").as(Map.class).get();
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- ABean a4b = c.getObject("a4", ABean.class);
+ ABean a4b = c.get("a4").as(ABean.class).orElse(null);
assertObject(a4b).asJson().is("{foo:'123'}");
assertObject(a4b).isType(ABean.class);
}
@@ -580,25 +580,25 @@ public class ConfigTest {
"\t)"
);
- Map a1 = c.getObject("a1", UonParser.DEFAULT, Map.class);
+ Map a1 = c.get("a1").as(UonParser.DEFAULT, Map.class).get();
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- List a2a = c.getObject("a2", UonParser.DEFAULT, List.class);
+ List a2a = c.get("a2").as(UonParser.DEFAULT, List.class).get();
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(((Map)a2a.get(0)).keySet().iterator().next()).isType(String.class);
assertObject(((Map)a2a.get(0)).values().iterator().next()).isType(Integer.class);
- Map a3 = c.getObject("a3", UonParser.DEFAULT, Map.class);
+ Map a3 = c.get("a3").as(UonParser.DEFAULT, Map.class).orElse(null);
assertNull(a3);
- Map a4a = c.getObject("a4", UonParser.DEFAULT, Map.class);
+ Map a4a = c.get("a4").as(UonParser.DEFAULT, Map.class).get();
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- ABean a4b = c.getObject("a4", UonParser.DEFAULT, ABean.class);
+ ABean a4b = c.get("a4").as(UonParser.DEFAULT, ABean.class).get();
assertObject(a4b).asJson().is("{foo:'123'}");
assertObject(a4b).isType(ABean.class);
}
@@ -618,34 +618,34 @@ public class ConfigTest {
"\t}"
);
- Map a1 = c.getObjectWithDefault("a1", new OMap(), Map.class);
+ Map a1 = c.get("a1").as(Map.class).orElseGet(OMap::new);
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- Map a1b = c.getObjectWithDefault("a1b", new OMap(), Map.class);
+ Map a1b = c.get("a1b").as(Map.class).orElseGet(OMap::new);
assertObject(a1b).asJson().is("{}");
- List a2a = c.getObjectWithDefault("a2", new OList(), List.class);
+ List a2a = c.get("a2").as(List.class).orElseGet(OList::new);
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(((Map)a2a.get(0)).keySet().iterator().next()).isType(String.class);
assertObject(((Map)a2a.get(0)).values().iterator().next()).isType(Integer.class);
- List a2b = c.getObjectWithDefault("a2b", new OList(), List.class);
+ List a2b = c.get("a2b").as(List.class).orElseGet(OList::new);
assertObject(a2b).asJson().is("[]");
- Map a3 = c.getObjectWithDefault("a3", new OMap(), Map.class);
+ Map a3 = c.get("a3").as(Map.class).orElseGet(OMap::new);
assertObject(a3).asJson().is("{}");
- Map a4a = c.getObjectWithDefault("a4", new OMap(), Map.class);
+ Map a4a = c.get("a4").as(Map.class).orElseGet(OMap::new);
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- Map a4b = c.getObjectWithDefault("a4b", new OMap(), Map.class);
+ Map a4b = c.get("a4b").as(Map.class).orElseGet(OMap::new);
assertObject(a4b).asJson().is("{}");
- ABean a4c = c.getObjectWithDefault("a4c", new ABean().init(), ABean.class);
+ ABean a4c = c.get("a4c").as(ABean.class).orElse(new ABean().init());
assertObject(a4c).asJson().is("{foo:'bar'}");
assertObject(a4c).isType(ABean.class);
}
@@ -665,34 +665,34 @@ public class ConfigTest {
"\t)"
);
- Map a1 = c.getObjectWithDefault("a1", UonParser.DEFAULT, new OMap(), Map.class);
+ Map a1 = c.get("a1").as(UonParser.DEFAULT, Map.class).orElseGet(OMap::new);
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- Map a1b = c.getObjectWithDefault("a1b", UonParser.DEFAULT, new OMap(), Map.class);
+ Map a1b = c.get("a1b").as(UonParser.DEFAULT, Map.class).orElseGet(OMap::new);
assertObject(a1b).asJson().is("{}");
- List a2a = c.getObjectWithDefault("a2", UonParser.DEFAULT, new OList(), List.class);
+ List a2a = c.get("a2").as(UonParser.DEFAULT, List.class).orElseGet(OList::new);
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(((Map)a2a.get(0)).keySet().iterator().next()).isType(String.class);
assertObject(((Map)a2a.get(0)).values().iterator().next()).isType(Integer.class);
- List a2b = c.getObjectWithDefault("a2b", UonParser.DEFAULT, new OList(), List.class);
+ List a2b = c.get("a2b").as(UonParser.DEFAULT, List.class).orElseGet(OList::new);
assertObject(a2b).asJson().is("[]");
- Map a3 = c.getObjectWithDefault("a3", UonParser.DEFAULT, new OMap(), Map.class);
+ Map a3 = c.get("a3").as(UonParser.DEFAULT, Map.class).orElseGet(OMap::new);
assertObject(a3).asJson().is("{}");
- Map a4a = c.getObjectWithDefault("a4", UonParser.DEFAULT, new OMap(), Map.class);
+ Map a4a = c.get("a4").as(UonParser.DEFAULT, Map.class).orElseGet(OMap::new);
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- Map a4b = c.getObjectWithDefault("a4b", UonParser.DEFAULT, new OMap(), Map.class);
+ Map a4b = c.get("a4b").as(UonParser.DEFAULT, Map.class).orElseGet(OMap::new);
assertObject(a4b).asJson().is("{}");
- ABean a4c = c.getObjectWithDefault("a4c", UonParser.DEFAULT, new ABean().init(), ABean.class);
+ ABean a4c = c.get("a4c").as(UonParser.DEFAULT, ABean.class).orElse(new ABean().init());
assertObject(a4c).asJson().is("{foo:'bar'}");
assertObject(a4c).isType(ABean.class);
}
@@ -700,6 +700,7 @@ public class ConfigTest {
//====================================================================================================
// public <T> T getObjectWithDefault(String key, T def, Type type, Type...args) throws ParseException {
//====================================================================================================
+ @SuppressWarnings("unchecked")
@Test
public void getObjectWithDefault3() throws Exception {
Config c = init(
@@ -711,34 +712,34 @@ public class ConfigTest {
"\t}"
);
- Map<String,Integer> a1 = c.getObjectWithDefault("a1", new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a1 = (Map<String,Integer>) c.get("a1").as(Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- Map<String,Integer> a1b = c.getObjectWithDefault("a1b", new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a1b = (Map<String,Integer>) c.get("a1b").as(Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a1b).asJson().is("{}");
- List<Map<String,Integer>> a2a = c.getObjectWithDefault("a2", new ArrayList<Map<String,Integer>>(), List.class, Map.class, String.class, Integer.class);
+ List<Map<String,Integer>> a2a = (List<Map<String,Integer>>) c.get("a2").as(List.class, Map.class, String.class, Integer.class).orElse(new ArrayList<Map<String,Integer>>());
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(a2a.get(0).keySet().iterator().next()).isType(String.class);
assertObject(a2a.get(0).values().iterator().next()).isType(Integer.class);
- List<ABean> a2b = c.getObjectWithDefault("a2b", new ArrayList<ABean>(), List.class, ABean.class);
+ List<ABean> a2b = (List<ABean>) c.get("a2b").as(List.class, ABean.class).orElse(new ArrayList<ABean>());
assertObject(a2b).asJson().is("[]");
- Map<String,Object> a3 = c.getObjectWithDefault("a3", new OMap(), Map.class, String.class, Object.class);
+ Map<String,Object> a3 = (Map<String,Object>) c.get("a3").as(Map.class, String.class, Object.class).orElse(new OMap());
assertObject(a3).asJson().is("{}");
- Map<String,Integer> a4a = c.getObjectWithDefault("a4", new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a4a = (Map<String,Integer>) c.get("a4").as(Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- Map<String,Integer> a4b = c.getObjectWithDefault("a4b", new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a4b = (Map<String,Integer>) c.get("a4b").as(Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a4b).asJson().is("{}");
- ABean a4c = c.getObjectWithDefault("a4c", new ABean().init(), ABean.class);
+ ABean a4c = c.get("a4c").as(ABean.class).orElse(new ABean().init());
assertObject(a4c).asJson().is("{foo:'bar'}");
assertObject(a4c).isType(ABean.class);
}
@@ -746,6 +747,7 @@ public class ConfigTest {
//====================================================================================================
// public <T> T getObjectWithDefault(String key, Parser parser, T def, Type type, Type...args) throws ParseException {
//====================================================================================================
+ @SuppressWarnings("unchecked")
@Test
public void getObjectWithDefault4() throws Exception {
Config c = init(
@@ -757,34 +759,34 @@ public class ConfigTest {
"\t)"
);
- Map<String,Integer> a1 = c.getObjectWithDefault("a1", UonParser.DEFAULT, new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a1 = (Map<String,Integer>) c.get("a1").as(UonParser.DEFAULT, Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a1).asJson().is("{foo:123}");
assertObject(a1.keySet().iterator().next()).isType(String.class);
assertObject(a1.values().iterator().next()).isType(Integer.class);
- Map<String,Integer> a1b = c.getObjectWithDefault("a1b", UonParser.DEFAULT, new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a1b = (Map<String,Integer>) c.get("a1b").as(UonParser.DEFAULT, Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a1b).asJson().is("{}");
- List<Map<String,Integer>> a2a = c.getObjectWithDefault("a2", UonParser.DEFAULT, new ArrayList<Map<String,Integer>>(), List.class, Map.class, String.class, Integer.class);
+ List<Map<String,Integer>> a2a = (List<Map<String,Integer>>) c.get("a2").as(UonParser.DEFAULT, List.class, Map.class, String.class, Integer.class).orElse(new ArrayList<Map<String,Integer>>());
assertObject(a2a).asJson().is("[{foo:123}]");
assertObject(a2a.get(0).keySet().iterator().next()).isType(String.class);
assertObject(a2a.get(0).values().iterator().next()).isType(Integer.class);
- List<ABean> a2b = c.getObjectWithDefault("a2b", UonParser.DEFAULT, new ArrayList<ABean>(), List.class, ABean.class);
+ List<ABean> a2b = (List<ABean>) c.get("a2b").as(UonParser.DEFAULT, List.class, ABean.class).orElse(new ArrayList<ABean>());
assertObject(a2b).asJson().is("[]");
- Map<String,Object> a3 = c.getObjectWithDefault("a3", UonParser.DEFAULT, new OMap(), Map.class, String.class, Object.class);
+ Map<String,Object> a3 = (Map<String,Object>) c.get("a3").as(UonParser.DEFAULT,Map.class, String.class, Object.class).orElse( new OMap());
assertObject(a3).asJson().is("{}");
- Map<String,Integer> a4a = c.getObjectWithDefault("a4", UonParser.DEFAULT, new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a4a = (Map<String,Integer>) c.get("a4").as(UonParser.DEFAULT, Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a4a).asJson().is("{foo:123}");
assertObject(a4a.keySet().iterator().next()).isType(String.class);
assertObject(a4a.values().iterator().next()).isType(Integer.class);
- Map<String,Integer> a4b = c.getObjectWithDefault("a4b", UonParser.DEFAULT, new HashMap<String,Integer>(), Map.class, String.class, Integer.class);
+ Map<String,Integer> a4b = (Map<String,Integer>) c.get("a4b").as(UonParser.DEFAULT, Map.class, String.class, Integer.class).orElse(new HashMap<String,Integer>());
assertObject(a4b).asJson().is("{}");
- ABean a4c = c.getObjectWithDefault("a4c", UonParser.DEFAULT, new ABean().init(), ABean.class);
+ ABean a4c = c.get("a4c").as(UonParser.DEFAULT, ABean.class).orElse(new ABean().init());
assertObject(a4c).asJson().is("{foo:'bar'}");
assertObject(a4c).isType(ABean.class);
}
@@ -1024,17 +1026,17 @@ public class ConfigTest {
"[section1]", "key1 = 2", "key2 = false", "key3 = [4,5,6]", "key4 = http://bar"
);
- assertEquals(1, cf.getInt("key1"));
- assertEquals(true, cf.getBoolean("key2"));
- assertEquals(3, cf.getObject("key3", int[].class)[2]);
- assertEquals(6, cf.getObjectWithDefault("xkey3", new int[]{4,5,6}, int[].class)[2]);
- assertEquals(6, cf.getObjectWithDefault("X/key3", new int[]{4,5,6}, int[].class)[2]);
- assertEquals(new URL("http://foo").toString(), cf.getObject("key4", URL.class).toString());
+ assertInteger(cf.get("key1").toInteger()).is(1);
+ assertBoolean(cf.get("key2").toBoolean()).isTrue();
+ assertInteger(cf.get("key3").to(int[].class)[2]).is(3);
+ assertInteger(cf.get("xkey3").as(int[].class).orElse(new int[]{4,5,6})[2]).is(6);
+ assertInteger(cf.get("X/key3").as(int[].class).orElse(new int[]{4,5,6})[2]).is(6);
+ assertEquals(new URL("http://foo").toString(), cf.get("key4").to(URL.class).toString());
- assertEquals(2, cf.getInt("section1/key1"));
- assertEquals(false, cf.getBoolean("section1/key2"));
- assertEquals(6, cf.getObject("section1/key3", int[].class)[2]);
- assertEquals(new URL("http://bar").toString(), cf.getObject("section1/key4", URL.class).toString());
+ assertInteger(cf.get("section1/key1").toInteger()).is(2);
+ assertBoolean(cf.get("section1/key2").toBoolean()).isFalse();
+ assertInteger(cf.get("section1/key3").to(int[].class)[2]).is(6);
+ assertEquals(new URL("http://bar").toString(), cf.get("section1/key4").to(URL.class).toString());
cf = init(
"# Default section",
@@ -1052,15 +1054,15 @@ public class ConfigTest {
cf.commit();
- assertEquals(1, cf.getInt("key1"));
- assertEquals(true, cf.getBoolean("key2"));
- assertEquals(3, cf.getObject("key3", int[].class)[2]);
- assertEquals(new URL("http://foo").toString(), cf.getObject("key4", URL.class).toString());
+ assertInteger(cf.get("key1").toInteger()).is(1);
+ assertBoolean(cf.get("key2").toBoolean()).isTrue();
+ assertInteger(cf.get("key3").to(int[].class)[2]).is(3);
+ assertEquals(new URL("http://foo").toString(), cf.get("key4").to(URL.class).toString());
- assertEquals(2, cf.getInt("section1/key1"));
- assertEquals(false, cf.getBoolean("section1/key2"));
- assertEquals(6, cf.getObject("section1/key3", int[].class)[2]);
- assertEquals(new URL("http://bar").toString(), cf.getObject("section1/key4", URL.class).toString());
+ assertInteger(cf.get("section1/key1").toInteger()).is(2);
+ assertBoolean(cf.get("section1/key2").toBoolean()).isFalse();
+ assertInteger(cf.get("section1/key3").to(int[].class)[2]).is(6);
+ assertEquals(new URL("http://bar").toString(), cf.get("section1/key4").to(URL.class).toString());
}
//====================================================================================================
@@ -1071,11 +1073,11 @@ public class ConfigTest {
Config cf = init(
"key1 = MINUTES"
);
- assertEquals(TimeUnit.MINUTES, cf.getObject("key1", TimeUnit.class));
+ assertEquals(TimeUnit.MINUTES, cf.get("key1").to(TimeUnit.class));
cf.commit();
- assertEquals(TimeUnit.MINUTES, cf.getObject("key1", TimeUnit.class));
+ assertEquals(TimeUnit.MINUTES, cf.get("key1").to(TimeUnit.class));
}
//====================================================================================================
@@ -1089,17 +1091,17 @@ public class ConfigTest {
cf.set("s1/foo", "mypassword");
- assertEquals("mypassword", cf.getString("s1/foo"));
+ assertEquals("mypassword", cf.get("s1/foo").get());
cf.commit();
assertString(cf).replaceAll("\\r?\\n", "|").is("[s1]||foo* = {AwwJVhwUQFZEMg==}|");
- assertEquals("mypassword", cf.getString("s1/foo"));
+ assertEquals("mypassword", cf.get("s1/foo").get());
cf.load(reader("[s1]\nfoo* = mypassword2\n"), true);
- assertEquals("mypassword2", cf.getString("s1/foo"));
+ assertEquals("mypassword2", cf.get("s1/foo").get());
cf.set("s1/foo", "mypassword");
@@ -1141,27 +1143,27 @@ public class ConfigTest {
System.getProperties().remove("baz");
System.getProperties().remove("bing");
- assertEquals("", cf.getString("s1/f1"));
- assertEquals("bar", cf.getString("s1/f2"));
- assertEquals("bar", cf.getString("s1/f3"));
+ assertEquals("", cf.get("s1/f1").get());
+ assertEquals("bar", cf.get("s1/f2").get());
+ assertEquals("bar", cf.get("s1/f3").get());
System.setProperty("foo", "123");
- assertEquals("123", cf.getString("s1/f1"));
- assertEquals("123", cf.getString("s1/f2"));
- assertEquals("bar", cf.getString("s1/f3"));
+ assertEquals("123", cf.get("s1/f1").get());
+ assertEquals("123", cf.get("s1/f2").get());
+ assertEquals("bar", cf.get("s1/f3").get());
System.setProperty("foo", "$S{bar}");
System.setProperty("bar", "baz");
- assertEquals("baz", cf.getString("s1/f1"));
- assertEquals("baz", cf.getString("s1/f2"));
- assertEquals("bar", cf.getString("s1/f3"));
+ assertEquals("baz", cf.get("s1/f1").get());
+ assertEquals("baz", cf.get("s1/f2").get());
+ assertEquals("bar", cf.get("s1/f3").get());
System.setProperty("bing", "$S{foo}");
- assertEquals("baz", cf.getString("s1/f3"));
+ assertEquals("baz", cf.get("s1/f3").get());
System.setProperty("baz", "foo");
System.setProperty("foo", "123");
- assertEquals("123", cf.getString("s1/f3"));
+ assertEquals("123", cf.get("s1/f3").get());
}
//====================================================================================================
@@ -1191,8 +1193,8 @@ public class ConfigTest {
Config cf = init().copy().binaryFormat(BinaryFormat.HEX).build();
cf.set("foo", "bar".getBytes("UTF-8"));
- assertEquals("626172", cf.get("foo"));
- assertObject(cf.getBytes("foo")).asJson().is("[98,97,114]");
+ assertEquals("626172", cf.get("foo").getValue());
+ assertObject(cf.get("foo").toBytes()).asJson().is("[98,97,114]");
}
//====================================================================================================
@@ -1203,8 +1205,8 @@ public class ConfigTest {
Config cf = init().copy().binaryFormat(BinaryFormat.SPACED_HEX).build();
cf.set("foo", "bar".getBytes("UTF-8"));
- assertEquals("62 61 72", cf.get("foo"));
- assertObject(cf.getBytes("foo")).asJson().is("[98,97,114]");
+ assertEquals("62 61 72", cf.get("foo").getValue());
+ assertObject(cf.get("foo").toBytes()).asJson().is("[98,97,114]");
}
//====================================================================================================
@@ -1217,7 +1219,7 @@ public class ConfigTest {
"f1 = x \n\ty \n\tz"
);
- assertEquals("x \ny \nz", cf.getString("s1/f1"));
+ assertEquals("x \ny \nz", cf.get("s1/f1").get());
StringWriter sw = new StringWriter();
cf.writeTo(sw);
@@ -1236,10 +1238,10 @@ public class ConfigTest {
"f3 = 1 M",
"f4 = 1 K"
);
- assertEquals(1048576, cf.getInt("s1/f1"));
- assertEquals(1024, cf.getInt("s1/f2"));
- assertEquals(1048576, cf.getInt("s1/f3"));
- assertEquals(1024, cf.getInt("s1/f4"));
+ assertInteger(cf.get("s1/f1").toInteger()).is(1048576);
+ assertInteger(cf.get("s1/f2").toInteger()).is(1024);
+ assertInteger(cf.get("s1/f3").toInteger()).is(1048576);
+ assertInteger(cf.get("s1/f4").toInteger()).is(1024);
}
//====================================================================================================
@@ -1360,34 +1362,34 @@ public class ConfigTest {
@Test
public void testGetObjectArray() throws Exception {
Config cf = init("[A]", "a1=[1,2,3]");
- assertObject(cf.getObject("A/a1", Integer[].class)).asJson().is("[1,2,3]");
- assertObject(cf.getObjectWithDefault("A/a2", new Integer[]{4,5,6}, Integer[].class)).asJson().is("[4,5,6]");
- assertObject(cf.getObjectWithDefault("B/a1", new Integer[]{7,8,9}, Integer[].class)).asJson().is("[7,8,9]");
- assertNull(cf.getObject("B/a1", Integer[].class));
+ assertObject(cf.get("A/a1").to(Integer[].class)).asJson().is("[1,2,3]");
+ assertObject(cf.get("A/a2").as(Integer[].class).orElse(new Integer[]{4,5,6})).asJson().is("[4,5,6]");
+ assertObject(cf.get("B/a1").as(Integer[].class).orElse(new Integer[]{7,8,9})).asJson().is("[7,8,9]");
+ assertNull(cf.get("B/a1").to(Integer[].class));
cf = init("[A]", "a1 = [1 ,\n\t2 ,\n\t3] ");
- assertObject(cf.getObject("A/a1", Integer[].class)).asJson().is("[1,2,3]");
+ assertObject(cf.get("A/a1").to(Integer[].class)).asJson().is("[1,2,3]");
// We cannot cast primitive arrays to Object[], so the following throws exceptions.
- assertObject(cf.getObject("A/a1", int[].class)).asJson().is("[1,2,3]");
- assertEquals("int", cf.getObject("A/a1", int[].class).getClass().getComponentType().getSimpleName());
- assertNull(cf.getObject("B/a1", int[].class));
- assertEquals("int", cf.getObjectWithDefault("B/a1", new int[0], int[].class).getClass().getComponentType().getSimpleName());
- assertNull(cf.getObject("A/a2", int[].class));
- assertEquals("int", cf.getObjectWithDefault("A/a2", new int[0], int[].class).getClass().getComponentType().getSimpleName());
-
- assertObject(cf.getObjectWithDefault("A/a1", new int[]{4}, int[].class)).asJson().is("[1,2,3]");
- assertEquals("int", cf.getObjectWithDefault("A/a1", new int[]{4}, int[].class).getClass().getComponentType().getSimpleName());
- assertObject(cf.getObjectWithDefault("B/a1", new int[]{4}, int[].class)).asJson().is("[4]");
- assertEquals("int", cf.getObjectWithDefault("B/a1", new int[]{4}, int[].class).getClass().getComponentType().getSimpleName());
- assertObject(cf.getObjectWithDefault("A/a2", new int[]{4}, int[].class)).asJson().is("[4]");
- assertEquals("int", cf.getObjectWithDefault("A/a2", new int[]{4}, int[].class).getClass().getComponentType().getSimpleName());
+ assertObject(cf.get("A/a1").to(int[].class)).asJson().is("[1,2,3]");
+ assertEquals("int", cf.get("A/a1").to(int[].class).getClass().getComponentType().getSimpleName());
+ assertNull(cf.get("B/a1").to(int[].class));
+ assertEquals("int", cf.get("B/a1").as(int[].class).orElse(new int[0]).getClass().getComponentType().getSimpleName());
+ assertNull(cf.get("A/a2").to(int[].class));
+ assertEquals("int", cf.get("A/a2").as(int[].class).orElse(new int[0]).getClass().getComponentType().getSimpleName());
+
+ assertObject(cf.get("A/a1").as(int[].class).orElse(new int[]{4})).asJson().is("[1,2,3]");
+ assertEquals("int", cf.get("A/a1").as(int[].class).orElse(new int[]{4}).getClass().getComponentType().getSimpleName());
+ assertObject(cf.get("B/a1").as(int[].class).orElse(new int[]{4})).asJson().is("[4]");
+ assertEquals("int", cf.get("B/a1").as(int[].class).orElse(new int[]{4}).getClass().getComponentType().getSimpleName());
+ assertObject(cf.get("A/a2").as(int[].class).orElse(new int[]{4})).asJson().is("[4]");
+ assertEquals("int", cf.get("A/a2").as(int[].class).orElse(new int[]{4}).getClass().getComponentType().getSimpleName());
System.setProperty("X", "[4,5,6]");
cf = init("x1=$C{A/a1}", "x2=$S{X}", "x3=$S{Y}", "[A]", "a1=[1,2,3]");
- assertObject(cf.getObjectWithDefault("x1", new int[]{9}, int[].class)).asJson().is("[1,2,3]");
- assertObject(cf.getObjectWithDefault("x2", new int[]{9}, int[].class)).asJson().is("[4,5,6]");
- assertObject(cf.getObjectWithDefault("x3", new int[]{9}, int[].class)).asJson().is("[9]");
+ assertObject(cf.get("x1").as(int[].class).orElse(new int[]{9})).asJson().is("[1,2,3]");
+ assertObject(cf.get("x2").as(int[].class).orElse(new int[]{9})).asJson().is("[4,5,6]");
+ assertObject(cf.get("x3").as(int[].class).orElse(new int[]{9})).asJson().is("[]");
System.clearProperty("X");
}
@@ -1398,19 +1400,19 @@ public class ConfigTest {
@Test
public void testGetStringArray() throws Exception {
Config cf = init("[A]", "a1=1,2,3");
- assertObject(cf.getStringArray("A/a1")).asJson().is("['1','2','3']");
- assertObject(cf.getStringArray("A/a2", new String[]{"4","5","6"})).asJson().is("['4','5','6']");
- assertObject(cf.getStringArray("B/a1", new String[]{"7","8","9"})).asJson().is("['7','8','9']");
- assertObject(cf.getStringArray("B/a1")).asJson().is("[]");
+ assertObject(cf.get("A/a1").toStringArray()).asJson().is("['1','2','3']");
+ assertObject(cf.get("A/a2").asStringArray().orElse(new String[]{"4","5","6"})).asJson().is("['4','5','6']");
+ assertObject(cf.get("B/a1").asStringArray().orElse(new String[]{"7","8","9"})).asJson().is("['7','8','9']");
+ assertObject(cf.get("B/a1").toStringArray()).isNull();
cf = init("[A]", "a1 = 1 ,\n\t2 ,\n\t3 ");
- assertObject(cf.getStringArray("A/a1")).asJson().is("['1','2','3']");
+ assertObject(cf.get("A/a1").toStringArray()).asJson().is("['1','2','3']");
System.setProperty("X", "4,5,6");
cf = init(null, "x1=$C{A/a1}", "x2=$S{X}", "x3=$S{Y}", "x4=$S{Y,$S{X}}", "[A]", "a1=1,2,3");
- assertObject(cf.getStringArray("x1", new String[]{"9"})).asJson().is("['1','2','3']");
- assertObject(cf.getStringArray("x2", new String[]{"9"})).asJson().is("['4','5','6']");
- assertObject(cf.getStringArray("x3", new String[]{"9"})).asJson().is("['9']");
+ assertObject(cf.get("x1").asStringArray().orElse(new String[]{"9"})).asJson().is("['1','2','3']");
+ assertObject(cf.get("x2").asStringArray().orElse(new String[]{"9"})).asJson().is("['4','5','6']");
+ assertObject(cf.get("x9").asStringArray().orElse(new String[]{"9"})).asJson().is("['9']");
System.clearProperty("X");
}
@@ -1464,22 +1466,22 @@ public class ConfigTest {
cf = cf.resolving(vr.createSession());
- assertEquals("aXa", cf.getString("a"));
- assertEquals("bXb", cf.getString("b"));
- assertEquals("abXba", cf.getString("c"));
- assertEquals("baXab", cf.getString("d"));
- assertEquals("$D{X}", cf.getString("e"));
+ assertEquals("aXa", cf.get("a").get());
+ assertEquals("bXb", cf.get("b").get());
+ assertEquals("abXba", cf.get("c").get());
+ assertEquals("baXab", cf.get("d").get());
+ assertEquals("$D{X}", cf.get("e").get());
// Create new resolver that addx $C and overrides $A
VarResolver vr2 = vr.copy().vars(AUVar.class, DUVar.class).build();
// true == augment by adding existing as parent to the new resolver
cf = cf.resolving(vr2.createSession());
- assertEquals("AXA", cf.getString("a"));
- assertEquals("bXb", cf.getString("b"));
- assertEquals("AbXbA", cf.getString("c"));
- assertEquals("bAXAb", cf.getString("d"));
- assertEquals("DXD", cf.getString("e"));
+ assertEquals("AXA", cf.get("a").get());
+ assertEquals("bXb", cf.get("b").get());
+ assertEquals("AbXbA", cf.get("c").get());
+ assertEquals("bAXAb", cf.get("d").get());
+ assertEquals("DXD", cf.get("e").get());
}
public static class ALVar extends SimpleVar {
@@ -1536,12 +1538,12 @@ public class ConfigTest {
cf.commit();
assertString(cf).replaceAll("\\r?\\n", "|").is("a = a,\\u0023b,=c|[A]|a = a,\\u0023b,=c|");
- assertEquals("a,#b,=c", cf.getString("a"));
- assertEquals("a,#b,=c", cf.getString("A/a"));
+ assertEquals("a,#b,=c", cf.get("a").get());
+ assertEquals("a,#b,=c", cf.get("A/a").get());
cf.set("a", "a,#b,=c", null, (ConfigMod)null, "comment#comment", null);
assertString(cf).replaceAll("\\r?\\n", "|").is("a = a,\\u0023b,=c # comment#comment|[A]|a = a,\\u0023b,=c|");
- assertEquals("a,#b,=c", cf.getString("a"));
+ assertEquals("a,#b,=c", cf.get("a").get());
}
public static class ABean {