[text] using a map as a value for StringSubstitutor

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[text] using a map as a value for StringSubstitutor

Nicolas Peltier
Hey here (hope i'm on the good list),

i have a StringSubstitutor use case where i'd need arbitrary level of depth
in my values, that could be hashmap containing hashmaps etc... to
substitute things like
"my ${job.name} is ${adjective.wealth.good}" and where i only put in the
initial map and hashmap at the key "job", and another at "adjective". Both
being filled as you guess it.

Should i write my own string lookup? or something exists already and i'm
overcomplicating things?

Nicolas
Reply | Threaded
Open this post in threaded view
|

Re: [text] using a map as a value for StringSubstitutor

Siegfried Goeschl-2
Hi Nicolas,

Either you simplify your setup so you have a flat map or you look into full-blown template engines ...

Thanks in advance,

Siegfried Goeschl

PS: In the Apache land there is FreeMarker & Velocity ...

> On 24.06.2020, at 20:12, Nicolas Peltier <[hidden email]> wrote:
>
> Hey here (hope i'm on the good list),
>
> i have a StringSubstitutor use case where i'd need arbitrary level of depth
> in my values, that could be hashmap containing hashmaps etc... to
> substitute things like
> "my ${job.name} is ${adjective.wealth.good}" and where i only put in the
> initial map and hashmap at the key "job", and another at "adjective". Both
> being filled as you guess it.
>
> Should i write my own string lookup? or something exists already and i'm
> overcomplicating things?
>
> Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [text] using a map as a value for StringSubstitutor

Siegfried Goeschl-2
In reply to this post by Nicolas Peltier
Or you can use something like https://docs.spring.io/spring-vault/docs/current/api/org/springframework/vault/support/JsonMapFlattener.html

> On 24.06.2020, at 20:12, Nicolas Peltier <[hidden email]> wrote:
>
> Hey here (hope i'm on the good list),
>
> i have a StringSubstitutor use case where i'd need arbitrary level of depth
> in my values, that could be hashmap containing hashmaps etc... to
> substitute things like
> "my ${job.name} is ${adjective.wealth.good}" and where i only put in the
> initial map and hashmap at the key "job", and another at "adjective". Both
> being filled as you guess it.
>
> Should i write my own string lookup? or something exists already and i'm
> overcomplicating things?
>
> Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: [text] using a map as a value for StringSubstitutor

garydgregory
Using 1.9-SNAPSHOT, you can do:

    private static final String SEPARATOR = ".";

    @SuppressWarnings("unchecked")
    private final BiFunction<String, Map<String, Object>, Object>
nestedMapBiFunction = (k, m) -> {
        final String keyCandidate = StringUtils.substringBefore(k,
SEPARATOR);
        if (keyCandidate.isEmpty()) {
            return m.get(k);
        }
        Object value = m.get(keyCandidate);
        if (value instanceof Map) {
            return
this.nestedMapBiFunction.apply(StringUtils.substringAfter(k, SEPARATOR),
                (Map<String, Object>) value);
        }
        return value;
    };

    @Test
    public void testBiFunctionForNestedMap() {
        // Build map
        final String subSubKey = "subsubkeyMap";
        final String subSubValue = "subsubvalue";
        final Map<String, String> subSubMap = new HashMap<>();
        subSubMap.put(subSubKey, subSubValue);
        //
        final String subKey = "subkey";
        final String subKeyMap = "subkeyMap";
        final String subValue = "subvalue";
        final Map<String, Object> rootSubMap = new HashMap<>();
        rootSubMap.put(subKey, subValue);
        rootSubMap.put(subKeyMap, subSubMap);
        //
        final String rootKey = "keyMap";
        final String rootKey2 = "key2";
        final String rootValue2 = "value2";
        final Map<String, Object> rootMap = new HashMap<>();
        rootMap.put(rootKey, rootSubMap);
        rootMap.put(rootKey2, rootValue2);
        // Use map
        final BiStringLookup<Map<String, Object>> stringLookup =
StringLookupFactory.INSTANCE
            .biFunctionStringLookup(nestedMapBiFunction);
        Assertions.assertEquals(rootValue2, stringLookup.lookup(rootKey2,
rootMap));
        Assertions.assertEquals(subValue, stringLookup.lookup(rootKey +
SEPARATOR + subKey, rootMap));
        Assertions.assertEquals(subSubValue,
            stringLookup.lookup(rootKey + SEPARATOR + subKeyMap + SEPARATOR
+ subSubKey, rootMap));
    }

See
https://github.com/apache/commons-text/blob/master/src/test/java/org/apache/commons/text/lookup/BiFunctionStringLookupTest.java

Gary

On Wed, Jun 24, 2020 at 2:38 PM Siegfried Goeschl <
[hidden email]> wrote:

> Or you can use something like
> https://docs.spring.io/spring-vault/docs/current/api/org/springframework/vault/support/JsonMapFlattener.html
>
> > On 24.06.2020, at 20:12, Nicolas Peltier <[hidden email]> wrote:
> >
> > Hey here (hope i'm on the good list),
> >
> > i have a StringSubstitutor use case where i'd need arbitrary level of
> depth
> > in my values, that could be hashmap containing hashmaps etc... to
> > substitute things like
> > "my ${job.name} is ${adjective.wealth.good}" and where i only put in the
> > initial map and hashmap at the key "job", and another at "adjective".
> Both
> > being filled as you guess it.
> >
> > Should i write my own string lookup? or something exists already and i'm
> > overcomplicating things?
> >
> > Nicolas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>