(the Transformative Tool)
Background: what NEW have I OSS’d lately?
It has been a while since I wrote a new tool or library of any kind (excluding Jackson modules)
In fact, my last new Open Source library must be be “Gorp” from 2018 — a nifty (*) multi-regexp library, inspired by Elastic’s “grok” — but one that I haven’t developed much further (**).
So I have thought about maybe writing something small, something different, to avoid getting too stuck with things I have “already done”.
(*) … or so I thought. :)
(**) nor likely to since no one else seems to have find it useful (or just not found it period)
Background: time to Do Some Docker
So towards end of 2020 I started thinking that I really needed to play more with some things with which I only had superficial familiarity (in their current forms), including Docker (and esp. docker builds) and the modern version of Spring Boot. The Thing — whatever it’d be — should do something useful, and might as well use some things that I have written before.
And finally, I should build something that is not (just) a library: for example, create an interactive service or tool of some kind. Something that can be directly used, not something that only works as embedded in something else.
This resulted in something I thought I might want to share with others, to see if anyone else finds it useful and/or interesting.
Tool to Do What?
But the immediate question aside from “let’s build a tool” was “what should the tool do?”.
Thinking about Jackson, as a low-level tool set, I realized that one big thing going on for Jackson is that it supports MANY different data formats — I keep writing about the fact that Jackson is “More than JSON” — and more than this, it exposes a unified processing model for working ACROSS formats; sometimes through POJO model (read JSON as Java Objects, write Java Objects as XML), sometimes using general-purpose tree model,
So it is, in fact, possible to do more or less direct conversions across most if not all formats — spoke-and-wheel style (N-to-N). This means that with about a dozen supported data formats (Jackson github repo lists 11 formats supported by FasterXML modules as well further 6 by third-party modules) we have over 100 conversion types, as well as potential further variations with some formatting aspects.
Now. A lot of every day SW Engineering these days is for integrating systems; and much of this has to do with relatively mundane transformations from one (input) data format into another (output) data format. Some of these conversions are mechanical; others not, but the way most data format parsing / generation libraries work is that they tend to focus on just one format: we have JSON libraries, XML libraries, CSV libraries. We also have some purpose-built converters for specific, more advanced cases (HTML to PDF etc).
But as I mentioned earlier, Jackson allows general transformations between, say:
pom.xml(XML content) into
JsonNode(Jackson 2.12 made this work much better than before
JsonNodeas, say, JSON, with pretty-printing. Or as Java Properties file if we are so inclined. Or maybe Avro or Protobuf document with suitable schema (which Jackson can generate, or use an existing external schema definition)
- Convert plain-old JSON into “binary” JSON variants like CBOR, MessagePack or Smile (and vice versa)
And then there was Jackformer
This simple idea lead to a simple (if not pretty (*)) web app that I dubbed “Jackformer” (it is a working title; could well change).
Once running (see the next section) Transformer requires you to select:
- Input format (with Jackson 2.x we could try using format auto-detection, but that only works for some of formats — and would lead to clunky flow)
- Output format (with some variations, for now wrt pretty-printing but may add variations for CSV)
- Input source (file upload or (for textual formats) text area)
- Result target (file download or (for textual formats) output in text area)
where “.pom” file looks something like:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
and if we select “Transform and Show” as the target we get:
which shows JSON-to-XML transformation in action.
(*) I never claimed to be a designer; some suspect (based on evidence) that I might be color-blind too :)
Running the Thing
As per Jackformer Github Repo at https://github.com/cowtowncoder/Jackformer — you can just clone the repository and run:
./mvnw clean spring-boot:run
to have an instance running locally, accessible on port 8080.
Or you can try using pre-built Docker image with:
docker run -p 8080:8080 cowtowncoder/jackformer-webapp:latest
This first version (0.5.1-SNAPSHOT) supports conversions between 10 input data formats and 9 output formats: ones that require Schema information are missing, for example.
- Avro and Protobuf require external schemas (or ones generated from POJOs)
- CSV input is accepted if (and only if) header row is used; output is not yet supported.
- TOML is not listed yet but I should add it since Jackson 2.12.3 includes backend!
These formats would not be difficult to support but require some additions to the UI to provide for schemas — and making this convenient to use would require some work (like allowing separate schema upload).
Feedback, contributions welcome!
At this point I don’t know if this thing is of use to others. It seems it might be but who knows? If you find it useful, check it out; let me know what you think.
And given how very rudimentary the whole thing is (especially, but not limited to all aspects of the User Interface :-) ), there are many things you could probably help improve!