lightbend / config

configuration library for JVM languages using HOCON files
https://lightbend.github.io/config/
6.16k stars 966 forks source link

Add support for Java 8 Time API #401

Open samekmichal opened 8 years ago

samekmichal commented 8 years ago

Currently, only parsing of Duration values is implemented. However, in the new java time API there are many more classes that would be nice to have parsed from the config files; such as

havocp commented 8 years ago

Durations seem very common in config files (timeouts, intervals, etc.) while I think this is the first feature request for dates and times. We can leave the issue open and see how often it comes up.

We do need to limit the size of our API at some point... to the extent that these would do a Config.getString and then pass the string to a parser from the JDK and no more, it may not be worth it to include these. Aside from frequency of use, durations are a bit different because we have to implement that parser/syntax ourselves.

But, let's leave the issue here to think about and for people to comment on. Thanks for bringing it up.

samekmichal commented 8 years ago

How about introducing some kind of plugin mechanism for parsers/codecs as is implemented for example in com.fasterxml.jackson.datatype and for the most common api have different artefacts.

Or simpler, just introducing a way how to "define" custom parsers.

havocp commented 8 years ago

What would that do though? It couldn't add methods to the Config interface could it? There's no need for anything special in the library other than to add methods there. The types like Duration aren't present on the parser level, they are interpretations of the already-parsed values. We only parse JSON types.

samekmichal commented 8 years ago

No, I probably didn't express myself correctly. I don't have any particular implementation in mind, but what I meant could be accomplished for example in a manner demonstrated in the following simplistic snippet.

  //Instantiated on a global level, filled with the modules/plugins
  final Map<Class<?>, Function<String, Object>> TYPE_FACTORIES = new HashMap<>();
  TYPE_FACTORIES.put(LocalDate.class, (Function<String, Object>) LocalDate::parse);

  public <T> T getOther(String path, Class<T> type) {
    final ConfigValue v = find(path, ConfigValueType.STRING);
    final Function<String, Object> valueFactory = TYPE_FACTORIES.get(type);
    if (valueFactory == null) {
      throw new ConfigException.WrongType(v.origin(), "Unregistered value");
    }
    final Object value = valueFactory.apply((String) v.unwrapped());
    return (T) value;
  }

The factories would be registered during runtime. Basically, they would not influence parsing in any way, only ease the construction of the desired value with a specific type (LocalDate, URI, ...), so the user in the end does not need to take care of this.

havocp commented 8 years ago

Got it. I would recommend writing functions that don't need the runtime registry; like static Day getDay(Config config, String path).

Maybe I'm missing some benefits of the registry though.

pie-flavor commented 8 years ago

A benefit of a registry would be that things can be registered and unregistered and reregistered at runtime. Not only can what Function is used to parse the value be changed at any point, but a value can be passed around from class to class, of some miscellaneous type, and parsed at the end, without any of the classes even knowing what type it is.

ugrepel commented 6 years ago

I'd second the request to allow direct parsing of dates and times. Think about cron style configuration values on when to run a certain job.

The biggest problem I see is the myriad of date/time formats. You'd either have to limit yourself to specific formats or you'd have to be able to define the format. Both options aren't really "nice".