Export system needs cleanup
- Dominant language
- Java
- Stars
- 25
- Forks
- 34
- PR merge metrics
- No merged PRs in 30d
Description
**Is your feature request related to a problem? Please describe.**
Extending exports to support direct exports (where the user directly exports to a Map or other) doesn't fit within the existing export system. The existing system has no concept of a callback, which is really needed to make it work. Additionally, there are several flaws & limitations with the existing export system:
* The existing `GroupExport` is incomplete in that it only exports the Properties directly contained in the class it is on and not contained inner classes. However, this cannot be changed to include contained classes because that would drastically change the current behavior. Instead, that behavior should be documented.
* It also cannot be applied to a containing class w/o Properties (it would just be ignored)
* There is partial code to have a bulk export to export all known Properties - this should be removed completely as this breaks the security model.
* `@ExportGroups` is in the internal package. It doesn't need to be there - where should it be?
* `StaticPropertyConfigurationInternal` really does not need a `getExportGroups()` method and we don't need to save that state in `AndHowCore` - it can be figured out on demand.
* For Properties w/ multiple out-aliases, there is no way to filter or indicate a preference.
* Unit testing the existing export system is very difficult
* Existing exports have unused methods and heavily rely on a base class for implementors, rather than a much simpler API which could have just been a single method.
**Describe the solution you'd like**
Rewrite the export system as:
* The bulk of the logic can move to an ExportService that is invoked to run an export
* Each individual Property that is to be export can be an individual callback to the actual export implementation.
* The existing, single exporter (System Properties) can continue to be used for that call back in existing application code.
* New implementations can also use that same mechanism to pass in a callback to use, including pre-built ones that do things like export to Map and Properties.
* The callback interface should have as much 'work' done as possible, so the lambda doesn't have to figure out export name preferences if it doesn't want to. There could be multiple signatures of the lambda: One with just the Property and flags and another that has everything pre-calculated.
* Possibly extend the 'out' export preferences to include a 'first out alias' or 'last out alias' option. This would allow simple distinctions in places where a property needs to be exported for two different uses.
* Support meta-annotations, so the the export annotations can be bundled into groups.
* The 'GroupExport' name is not clear - Perhaps create a new one called 'AutoExport`.
* New `AllowExport` should take preferences as well to use as defaults for manual export.
* There should be good defaults for the automatic export so they don't always need to be spec'ed. I think the most obvious defaults would be:
* Default to exporting out-aliases ALWAYS and canonical if no out alias
* It would be nice to also be able to block some subgroups with an `@ExportGroupNotAllowed`.
* For exporting to a file, it might be nice to mark classes as `@AutoExport`, then have the export details in the `AndHowInit`. For instance, if integrating w/ another process, have AndHow write to a file on the FS for that process to read, which could be machine dependent. There could even be a parallel structure here of Loaders and Exporters that could be part of the `AndHowConfig` API.
Invocation might look like:
`Map map = AndHow.instance().export(ExportToStringMap.class);` or
`Map map = AndHow.instance().export(p -> myLambda(p));`
### Insights / Realizations
* The current 'auto' exports are really completely separate from the planned feature of 'manual' exports. Settings for one (export canonical names or not) don't apply to the other b/c they will be for completely different uses.
* Even different types of 'auto' exports (although there is only one) shouldn't share preferences and should happen separately.
* The existing auto-export annotation, `GroupExport`, is incomplete in that it only exports the Properties directly contained in the class it is on and not contained inner classes. However, this cannot be changed to include contained classes because that would drastically change the current behavior. Instead, that behavior should be documented.
* New annotations could be created with explicit behaviors, like `AutoExportWithChilren' and `AutoExportWithoutChildren`
* Given all this and the fact that exports happen early int he lifecycle and likely never again, it doesn't make sense to permanently store export settings in GroupProxies or other places, even if export code is inefficient.
**Describe alternatives you've considered**
An alternative would be to wait until a major release, since this affects public API. However, the only this affects users is if someone has created a custom exporter, which is very unlikely.
Also considered having an option to inherit containing class options for exports. This just adds complexity for no reason. It doesn't help to inherit because options would have been inherited simply by not placing an annotation. its also very visible because its all in one file. If that is not flexible enough, a manual export will eventually be available.
Contributor guide
Assessment
This issue has not been assessed yet.