Date: 2020-07-26
Author: Ben Weidig
Add modern Java 8 features to tapestry-json to make it more versatile. Improve existing functionality without breaking changes.
With Tapestry development picking up speed and supporting newer Java version, its dependencies should also support some of the newly available features:
- Stream-support
- Additional instance creators
- Approximate to the conceptional interfaces (Collection/Map)
- Generic methods
- Better/more informative exceptions
The general idea is making JSONArray
more like java.util.Collection
, and JSONObject
more like java.util.Map
, without implementing the interfaces explicitly.
If we would implement them directly, it would method duplication (size()
vs. length()
, add()
vs put(...)
).
Tapestry's use of JSON types is deeply ingrained into its services. By using its own types, we can improve upon them to adapt to any new features. The framework and Java itself evolved, and they should be too.
Java 8 was bringing a lot of new features, like lambdas, Streams, and Optionals, thereby changing the way how we can deal with collection types in a significant way.
It's time to adapt tapestry-json to the new features available to us.
Only minimal risk is assumed.
Existing functionality shouldn't be changed, for backward-compatibility. Any new feature has to be able to stand on its own.
The only proposed change will be the exact exception types and messages.
Changing the type should not pose a problem, they will still be descendant of RuntimeException
.
And relying on the actual exception message is bad practice, and shouldn't be part of the guaranteed API contract.
Instead of extending existing types we could always use utility classes to wrap the functionality.
Most of the proposed changes are based on utility classes used in our projects. But some are just of theoretical nature, and might not be as easy as implementable as thought.
Stream<Object> stream()
Stream<T> stream(Class<T> clazz)
Stream<Object> parallelStream()
Stream<T> parallelStream(Class<T> clazz)
List<T> toList(Class<T> clazz)
static JSONArray from(Iterable<?> iterable, boolean preserveNull)
JSONArray(String jsonStr, boolean emptyIfInvalid)
boolean putUnique(Object value)
boolean isEmpty()
boolean contains(Object obj)
boolean removeIf(Predicate<Object> filter)
boolean removeAll(Iterable<Object> iterable)
void clear()
Map<String, T> toMap(Class<T> valueClazz)
Optional<Type> tryGetType(String key)
for all typesType getType(String key, Type fallbackValue)
for all typesstatic JSONObject from(Map<String, ?> map)
void clear()
void clear()
Object putIfAbsent(String key, Object value)
Object computeIfAbsent(String key, Function<String, Object> mapFn)
Object computeIfPresent(String key, Function<String, Object> remapFn)
void merge(JSONObject other)
- Use
IndexOutOfBoundsException
correctly org.apache.tapestry5.json.JSON
should throw more fine-grained exceptions:- Add
JSONTypeUnsupportedException
- Add
JSONTypeMismatchException
- Add
JSONValueNotFoundException
- Add
- Add Collectors to improve
Stream
use
All added functionality should be unit tested to ensure no existing code will be broken by it.
Hi Ben, just a friendly follow-up to see how you are progressing with this proposed improvement? All the best, Chris.