From 2c88a5b1db5422491e7fe1157a6fa8c5eead71fa Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 08:53:51 -0400 Subject: [PATCH 1/9] Add design spec for Jackson 3 migration (#430) Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- docs/specs/Jackson-3-Migration-Design.md | 142 +++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 docs/specs/Jackson-3-Migration-Design.md diff --git a/docs/specs/Jackson-3-Migration-Design.md b/docs/specs/Jackson-3-Migration-Design.md new file mode 100644 index 00000000..fa11fa7c --- /dev/null +++ b/docs/specs/Jackson-3-Migration-Design.md @@ -0,0 +1,142 @@ +# Migrate to Jackson 3 (`tools.jackson`) — JSONata4Java 3.0.0 + +**Issue:** [#430](https://github.com/IBM/JSONata4Java/issues/430) — Migrate code from +`com.fasterxml.jackson.core` to `tools.jackson.core`. + +## Summary + +Jackson 3.0 renamed both its Maven group-ids and Java packages from `com.fasterxml.jackson` +to `tools.jackson`, made the core exception hierarchy unchecked, and moved mapper +configuration to an immutable builder pattern. JSONata4Java exposes +`com.fasterxml.jackson.databind.JsonNode` throughout its public API, so migrating to Jackson 3 +is a breaking change and warrants a new major version. + +The project's `pom.xml` already stages the transition by listing both the Jackson 2.x and +Jackson 3.x dependencies. This work completes the cutover: remove the 2.x stack, migrate all +source and test code to `tools.jackson`, and release as **3.0.0**. + +## Decisions + +- **Strategy: hard cutover.** Replace all `com.fasterxml.jackson.*` usage with `tools.jackson.*` + and drop the 2.x dependencies entirely. No dual-support/abstraction layer (JsonNode is woven + too deeply into the public API to make that worthwhile — YAGNI). +- **Version: 3.0.0.** Bump from `2.6.4`. The public-API break (JsonNode package change) requires + a major version. +- **XML in scope.** Port the `XmlMapper`/`ToXmlGenerator` usage to Jackson 3's + `tools.jackson.dataformat.xml`. +- **CLI/UI helpers in scope.** `Tester`, `TesterTimeBox`, `TesterUI`, and `Test` are migrated + along with the core library, even though they carry most of the API churn. +- **Target dependency version: 3.2.0** (current Jackson 3 line; confirmed published on Maven + Central for both `jackson-databind` and `jackson-dataformat-xml`). + +## Scope + +103 Java files reference Jackson today: 87 under `src/main/java`, 16 under `src/test/java`. +The overwhelming majority only use JSON node types whose class names are unchanged in Jackson 3 +— only the package prefix moves. + +## Dependency changes (`pom.xml`) + +| Action | Coordinates | +| --- | --- | +| Remove | `com.fasterxml.jackson.core:jackson-databind:2.22.0` | +| Remove | `com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.22.0` | +| Keep | `tools.jackson.core:jackson-databind:3.2.0` (already present) | +| Add | `tools.jackson.dataformat:jackson-dataformat-xml:3.2.0` | +| Keep | `com.fasterxml.woodstox:woodstox-core:7.2.1` (Jackson 3 XML still uses Stax/woodstox) | +| Keep | `re2j` (test), `gson`, `commons-text`, `antlr4-runtime`, `spring-context` (test), `junit` (test) | +| Change | `` `2.6.4` → `3.0.0` | + +Notes: +- `jackson-core` is pulled in transitively by `jackson-databind`; no direct entry needed. +- **`jackson-annotations` was NOT renamed** — it stays under `com.fasterxml.jackson.annotation`. + The codebase has no annotation imports, so this is a non-issue here, but do not blindly + rewrite `com.fasterxml.jackson.annotation` should it appear. + +## Migration approach + +Execute in three passes so the risky hand-edits stay isolated from the bulk mechanical change. + +### Pass 1 — Mechanical package rename (~103 files) + +Scripted find-replace across `src/main/java` and `src/test/java`, longest-prefix first to avoid +double rewriting: + +1. `com.fasterxml.jackson.dataformat.xml` → `tools.jackson.dataformat.xml` +2. `com.fasterxml.jackson.databind` → `tools.jackson.databind` +3. `com.fasterxml.jackson.core` → `tools.jackson.core` + +This covers all the node types (`JsonNode`, `JsonNodeFactory`, `ArrayNode`, `ObjectNode`, +`TextNode`, `LongNode`, `IntNode`, `DoubleNode`, `FloatNode`, `BooleanNode`, `NullNode`, +`POJONode`, `ValueNode`, `NumericNode`, `JsonNodeType`) and the streaming/databind entry points, +all of which keep their simple class names in Jackson 3. + +### Pass 2 — Hand-fix API-change hotspots (< 10 files) + +These sites use APIs that changed shape in Jackson 3 and will not compile after a pure rename. + +**Mapper configuration → immutable builder.** In Jackson 3, mappers are immutable; the mutating +`enable`/`configure`/`getFactory().configure(...)` methods are gone. All affected sites are in +CLI/UI helpers, not the core library: + +- `Tester.java:124` — `mapper.getFactory().configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), true)` + → construct via `JsonMapper.builder().enable(JsonWriteFeature.ESCAPE_NON_ASCII).build()`. + `JsonWriteFeature` moves to `tools.jackson.core`. +- `TesterUI.java:108` — `xmlMapper.enable(SerializationFeature.INDENT_OUTPUT)` + → set in the `XmlMapper.builder()...build()` chain. +- `TesterUI.java:488–491` — `xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true)`, + `xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true)`, + `xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_1_1, true)` + → fold into the `XmlMapper.builder()` chain (verify the `ToXmlGenerator.Feature` enum location + under `tools.jackson.dataformat.xml`). + +**Plain mapper construction.** Sites that only call `readTree` / `writeValueAsString` on a +`new ObjectMapper()` (in `Binding`, `ExpressionsVisitor`, `ContainsFunction`, `Expression`, +`JSONataUtils`, `Issue180`, `Test`) need only the package rename; keep `new ObjectMapper()` (or +switch to `JsonMapper.shared()` / `new JsonMapper()` if `new ObjectMapper()` proves unavailable). +The exact constructor availability is confirmed at compile time in Pass 3. + +**Unchecked exceptions.** `JsonProcessingException`'s parent became `RuntimeException` and core +introduced unchecked `JacksonException`. Catch blocks referencing `JsonProcessingException` +generally still compile because it is now unchecked. Where a `catch (JsonProcessingException e)` +becomes unreachable, or the type is no longer resolvable, replace with +`tools.jackson.core.JacksonException`. Review each multi-catch +(`EvaluateException | JsonProcessingException`) individually. Affected files: `TesterTimeBox`, +`Test`, `Tester`, `TesterUI`, `ExpressionsVisitor`, `Issue180`. + +### Pass 3 — Compile, test, verify + +- `mvn clean compile` — resolve any remaining API breaks surfaced by the compiler; iterate until + clean. +- `mvn test` — the existing unit tests plus `AgnosticTestSuite` are the correctness safety net; + the 16 migrated test files run here too. +- Manually exercise the `Tester` CLI (JSON read/pretty-print path) and, where feasible, the Swing + `TesterUI` XML↔JSON conversion, since those hold the most API churn. + +## Build configuration + +- **OSGi (`bnd-maven-plugin`).** The `Export-Package` list references only `com.api.jsonata4java.*` + and needs no change. Confirm the generated `MANIFEST.MF` `Import-Package` header now imports + `tools.jackson.*` rather than `com.fasterxml.jackson.*`. +- **JPMS.** No `module-info.java` exists; no module changes required. +- No other plugin configuration references Jackson. + +## Out of scope + +- Any behavioral changes beyond what the package/API migration requires. +- Adopting new Jackson 3 features (e.g., new default flips such as `FAIL_ON_UNKNOWN_PROPERTIES`) + beyond preserving existing behavior. If a Jackson 3 default change alters observed test + behavior, restore the prior behavior via builder configuration rather than accepting the new + default silently. +- Unrelated refactoring of the touched files. + +## Risks / watch-items + +- **Default-value flips in Jackson 3** (e.g., `WRITE_DATES_AS_TIMESTAMPS`, `FAIL_ON_UNKNOWN_PROPERTIES`) + could shift test output. The test suite is the detector; restore prior behavior via builder + config where a test regresses. +- **`ToXmlGenerator.Feature` and `JsonWriteFeature` relocations** — confirm exact package/enum + homes at compile time; the builder `enable(...)` overloads may differ from the 2.x + `configure(feature, boolean)` shape. +- **`new ObjectMapper()` availability** — if the no-arg constructor is unavailable/discouraged in + 3.x, fall back to `JsonMapper.shared()` or `new JsonMapper()`. From 60840615a7710ae1b4d7d7564805b3ee051ed73a Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 09:06:23 -0400 Subject: [PATCH 2/9] Add implementation plan for Jackson 3 migration (#430) Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- docs/plans/Jackson-3-Migration-Plan.md | 284 +++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 docs/plans/Jackson-3-Migration-Plan.md diff --git a/docs/plans/Jackson-3-Migration-Plan.md b/docs/plans/Jackson-3-Migration-Plan.md new file mode 100644 index 00000000..9bd98af3 --- /dev/null +++ b/docs/plans/Jackson-3-Migration-Plan.md @@ -0,0 +1,284 @@ +# Jackson 3 Migration Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Migrate JSONata4Java from Jackson 2.x (`com.fasterxml.jackson.*`) to Jackson 3.x (`tools.jackson.*`) and release as version 3.0.0. + +**Architecture:** Hard cutover. Both Jackson 2.x and 3.x deps are currently present in `pom.xml`, so we exploit that overlap: add the Jackson 3 XML dataformat, migrate all source/test code to `tools.jackson`, get it compiling and green against Jackson 3, then remove the 2.x deps and bump the version. This keeps every task boundary in a compiling, tested state. + +**Tech Stack:** Java 17, Maven, Jackson 3.2.0 (`tools.jackson.core:jackson-databind`, `tools.jackson.dataformat:jackson-dataformat-xml`), ANTLR4, JUnit 4, woodstox-core (Stax backend for XML). + +## Global Constraints + +- Target Jackson version: **3.2.0** for both `jackson-databind` and `jackson-dataformat-xml`. +- Project version becomes **3.0.0** (from `2.6.4`). +- `jackson-annotations` is **not** renamed — never rewrite `com.fasterxml.jackson.annotation` (none present today). +- No behavioral changes beyond what the migration requires; if a Jackson 3 default flip changes test output, restore prior behavior via builder config rather than accept the new default. +- No `module-info.java` exists; do not add one. +- Reference spec: `docs/specs/Jackson-3-Migration-Design.md`. +- Commit messages end with the `Co-Authored-By: Claude Opus 4.8 ` trailer. + +--- + +### Task 1: Add Jackson 3 XML dataformat dependency + +Adds the Jackson 3 XML library alongside the existing deps so that when `TesterUI` is renamed to `tools.jackson.dataformat.xml` in Task 2 it has something to compile against. The 2.x deps stay for now; the code still compiles because it still imports `com.fasterxml.jackson.*`. + +**Files:** +- Modify: `pom.xml` (dependencies section, near the existing `tools.jackson.core:jackson-databind` entry around line 105) + +**Interfaces:** +- Consumes: nothing. +- Produces: the Maven coordinate `tools.jackson.dataformat:jackson-dataformat-xml:3.2.0` available on the compile classpath for later tasks. + +- [ ] **Step 1: Add the dependency** + +In `pom.xml`, immediately after the existing `tools.jackson.core:jackson-databind` dependency block, add: + +```xml + + + tools.jackson.dataformat + jackson-dataformat-xml + 3.2.0 + compile + +``` + +- [ ] **Step 2: Verify it resolves and the project still compiles** + +Run: `mvn -q -DskipTests clean compile` +Expected: BUILD SUCCESS (code is still on `com.fasterxml.jackson.*`, both stacks present). + +- [ ] **Step 3: Confirm the coordinate is on the tree** + +Run: `mvn -q dependency:tree | grep jackson-dataformat-xml` +Expected: shows both `com.fasterxml.jackson.dataformat:jackson-dataformat-xml:jar:2.22.0` and `tools.jackson.dataformat:jackson-dataformat-xml:jar:3.2.0`. + +- [ ] **Step 4: Commit** + +```bash +git add pom.xml +git commit -m "Add Jackson 3 XML dataformat dependency (#430) + +Co-Authored-By: Claude Opus 4.8 " +``` + +--- + +### Task 2: Migrate all source and test code to `tools.jackson` + +The core of the migration. Run the scripted package rename across all Java sources, then hand-fix the API-change hotspots until the whole project compiles and the full test suite is green against Jackson 3. The task deliverable is a green `mvn test` with all code on `tools.jackson.*`. + +**Files:** +- Modify: every `.java` under `src/main/java` and `src/test/java` that imports Jackson (~103 files) — bulk rename. +- Modify (hand): `src/main/java/com/api/jsonata4java/Tester.java` +- Modify (hand): `src/main/java/com/api/jsonata4java/testerui/TesterUI.java` +- Modify (hand, as compiler dictates): `TesterTimeBox.java`, `Test.java`, `ExpressionsVisitor.java`, `issues/Issue180.java` + +**Interfaces:** +- Consumes: `tools.jackson.dataformat:jackson-dataformat-xml:3.2.0` (Task 1) and `tools.jackson.core:jackson-databind:3.2.0` (already in pom). +- Produces: entire codebase importing `tools.jackson.*`; public API now exposes `tools.jackson.databind.JsonNode`. No new public method names introduced. + +- [ ] **Step 1: Run the scripted package rename** + +Longest-prefix-first so `dataformat.xml` and `databind`/`core` don't double-rewrite. Run from the repo root: + +```bash +find src/main/java src/test/java -name '*.java' -print0 | xargs -0 perl -pi -e ' + s/\Qcom.fasterxml.jackson.dataformat.xml\E/tools.jackson.dataformat.xml/g; + s/\Qcom.fasterxml.jackson.databind\E/tools.jackson.databind/g; + s/\Qcom.fasterxml.jackson.core\E/tools.jackson.core/g; +' +``` + +- [ ] **Step 2: Confirm no `com.fasterxml.jackson` core/databind/xml references remain** + +Run: `grep -rn "com.fasterxml.jackson.core\|com.fasterxml.jackson.databind\|com.fasterxml.jackson.dataformat" src/ || echo CLEAN` +Expected: `CLEAN` (annotations, if any ever appear, are intentionally left; none exist today). + +- [ ] **Step 3: Compile to surface the hotspots** + +Run: `mvn -q -DskipTests clean compile 2>&1 | tee /tmp/j3-compile.log | tail -40` +Expected: FAILS — errors concentrated in `Tester.java` (`getFactory().configure`, `JsonWriteFeature.mappedFeature()`) and `TesterUI.java` (`xmlMapper.enable`/`.configure`, `ToXmlGenerator.Feature`). Note each reported file:line. + +- [ ] **Step 4: Fix `Tester.java` mapper construction** + +Jackson 3 mappers are immutable — `getFactory().configure(...)` and the 2.x `JsonWriteFeature.mappedFeature()` bridge are gone. Replace the two lines at the top of `main(...)`: + +Old: +```java + ObjectMapper mapper = new ObjectMapper(); + mapper.getFactory().configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), true); +``` +New: +```java + JsonMapper mapper = JsonMapper.builder() + .enable(JsonWriteFeature.ESCAPE_NON_ASCII) + .build(); +``` + +Update imports in `Tester.java`: remove `import tools.jackson.databind.ObjectMapper;`, add `import tools.jackson.databind.json.JsonMapper;`. Keep `import tools.jackson.core.json.JsonWriteFeature;` (the rename already moved it out of `com.fasterxml`). If the compiler reports `JsonWriteFeature` is not in `tools.jackson.core.json`, follow the compiler's suggested package (Jackson 3 relocated some feature enums) — it is a streaming write feature under `tools.jackson.core`. + +- [ ] **Step 5: Fix `TesterUI.java` mapper fields and XML config** + +The `xmlMapper` field needs all its features set at build time (immutable mapper). Find the field declarations (around lines 75-76): + +Old: +```java + private final ObjectMapper jsonMapper = new ObjectMapper(); + private final XmlMapper xmlMapper = new XmlMapper(); +``` +New: +```java + private final ObjectMapper jsonMapper = new ObjectMapper(); + private final XmlMapper xmlMapper = XmlMapper.builder() + .enable(SerializationFeature.INDENT_OUTPUT) + .enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION) + .enable(ToXmlGenerator.Feature.WRITE_XML_1_1) + .build(); +``` + +Then delete the now-redundant mutating calls: +- In the constructor (around line 108): delete the line `xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);` +- In `jsonToXml(...)` (around lines 488-490): delete the three lines + ```java + xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true); + xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true); + xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_1_1, true); + ``` + Leave the rest of `jsonToXml` (`ObjectWriter ow = xmlMapper.writer().withRootName("root");` etc.) intact. + +If `new ObjectMapper()` is rejected by the compiler, replace it with `new JsonMapper()` (import `tools.jackson.databind.json.JsonMapper`) — a `JsonMapper` is-a `ObjectMapper` in Jackson 3. If `XmlMapper.builder().enable(...)` does not accept a given feature enum, consult the compiler message for the correct builder method; the three features are: pretty-print (`SerializationFeature.INDENT_OUTPUT`), XML declaration, and XML 1.1. + +- [ ] **Step 6: Recompile and fix any remaining API breaks** + +Run: `mvn -q -DskipTests clean compile 2>&1 | tee /tmp/j3-compile.log | tail -40` +Expected: iterate until BUILD SUCCESS. Likely remaining items: unreachable `catch (JsonProcessingException e)` clauses — Jackson 3 made it unchecked, so a lone catch of it is still legal, but if the compiler flags any catch as unreachable, change that type to `tools.jackson.core.JacksonException`. Do not touch `IOException` catches. Files that may need this: `Tester.java`, `TesterTimeBox.java`, `Test.java`, `TesterUI.java`, `ExpressionsVisitor.java`, `issues/Issue180.java`. + +- [ ] **Step 7: Run the full test suite** + +Run: `mvn -q test 2>&1 | tail -30` +Expected: BUILD SUCCESS. This runs the unit tests and `AgnosticTestSuite` (the regression safety net), including the 16 migrated test files. + +- [ ] **Step 8: If any test regressed, restore prior behavior** + +If a test fails due to a Jackson 3 default change (e.g. `WRITE_DATES_AS_TIMESTAMPS`, `FAIL_ON_UNKNOWN_PROPERTIES`), fix by configuring the relevant mapper's builder to the 2.x behavior at its construction site — not by editing the test's expectation. Re-run `mvn -q test` until green. + +- [ ] **Step 9: Commit** + +```bash +git add -A +git commit -m "Migrate source and tests to Jackson 3 (tools.jackson) (#430) + +Co-Authored-By: Claude Opus 4.8 " +``` + +--- + +### Task 3: Remove Jackson 2.x dependencies and bump version to 3.0.0 + +With all code on Jackson 3 and tests green, drop the now-unused 2.x deps and cut the major version. + +**Files:** +- Modify: `pom.xml` — remove two dependency blocks, change ``. + +**Interfaces:** +- Consumes: green build from Task 2. +- Produces: a classpath with no `com.fasterxml.jackson.core`/`databind`/`dataformat.xml` 2.x jars; project version `3.0.0`. + +- [ ] **Step 1: Remove the Jackson 2.x dependency blocks** + +In `pom.xml`, delete these two blocks: +```xml + + com.fasterxml.jackson.core + jackson-databind + 2.22.0 + +``` +```xml + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.22.0 + +``` +Leave `com.fasterxml.woodstox:woodstox-core` in place — Jackson 3 XML still uses it. + +- [ ] **Step 2: Bump the project version** + +Change the top-level project version: +Old: ` 2.6.4` +New: ` 3.0.0` + +- [ ] **Step 3: Verify no Jackson 2.x remains on the dependency tree** + +Run: `mvn -q dependency:tree | grep "com.fasterxml.jackson" || echo NONE` +Expected: only `com.fasterxml.woodstox:woodstox-core` may appear; no `com.fasterxml.jackson.core`, `...databind`, or `...dataformat.jackson-*` 2.x entries. (Note: `jackson-annotations` under `com.fasterxml.jackson` may appear transitively via Jackson 3 — that is expected and correct.) + +- [ ] **Step 4: Full clean build + tests** + +Run: `mvn -q clean test 2>&1 | tail -30` +Expected: BUILD SUCCESS with only Jackson 3 (plus jackson-annotations 2.x, woodstox) on the classpath. + +- [ ] **Step 5: Commit** + +```bash +git add pom.xml +git commit -m "Drop Jackson 2.x deps, bump to 3.0.0 (#430) + +Co-Authored-By: Claude Opus 4.8 " +``` + +--- + +### Task 4: Verify OSGi manifest and exercise CLI/XML paths + +Confirm the packaged artifact's OSGi metadata now imports `tools.jackson.*`, and smoke-test the two entry points that carry the most API churn. + +**Files:** +- No source changes expected. If verification fails, fixes route back to Task 2/3. + +**Interfaces:** +- Consumes: green build from Task 3. +- Produces: verified runnable artifact; confirmation that no `com.fasterxml.jackson` import remains in the bundle manifest. + +- [ ] **Step 1: Package the jar (runs the bnd OSGi plugin)** + +Run: `mvn -q -DskipTests package 2>&1 | tail -15` +Expected: BUILD SUCCESS; produces `target/JSONata4Java-3.0.0.jar`. + +- [ ] **Step 2: Inspect the generated OSGi Import-Package header** + +Run: `unzip -p target/JSONata4Java-3.0.0.jar META-INF/MANIFEST.MF | tr -d '\r' | grep -A40 "Import-Package"` +Expected: imports reference `tools.jackson.*`; no `com.fasterxml.jackson.core`/`databind`/`dataformat.xml` imports (a `com.fasterxml.jackson.annotation` import, if present, is acceptable). + +- [ ] **Step 3: Smoke-test the Tester CLI** + +Run: +```bash +echo "q" | java -cp target/JSONata4Java-3.0.0-jar-with-dependencies.jar com.api.jsonata4java.Tester null +``` +Expected: prints the pretty-printed default JSON (`Using json:` block) then `Goodbye`, with no exception/stack trace. + +- [ ] **Step 4: Verify the XML round-trip logic (TesterUI)** + +`TesterUI` is a Swing app; verify its `jsonToXml`/`xmlToJson` logic compiles and runs headlessly by confirming the package build already exercised `XmlMapper.builder()`. If a manual check is desired, run the UI on a machine with a display: +```bash +java -cp target/JSONata4Java-3.0.0-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI +``` +Expected: window opens; using the JSON→XML and XML→JSON conversion produces indented XML with an XML declaration and valid JSON, respectively. (Skip if no display is available; the compile in Task 2 already validated the API usage.) + +- [ ] **Step 5: Final confirmation (no commit unless fixes were made)** + +Run: `git status` +Expected: clean tree (Tasks 1-3 already committed). If Step 2/3 forced a code fix, commit it with a message referencing `#430`. + +--- + +## Notes for the implementer + +- The rename in Task 2 Step 1 is the bulk of the change but is purely mechanical; the real work is Steps 4-8. Do not skip the compile-and-iterate loop. +- Jackson 3's exact builder method names for XML features (`ToXmlGenerator.Feature`) and the home of `JsonWriteFeature` should be confirmed against compiler output rather than assumed — the plan gives the expected shape, the compiler is the authority. +- Keep `woodstox-core`: removing it will break XML parsing at runtime even though compilation succeeds. From 8f02185cd956014e6ff8dcf2eae214ea6f1f5762 Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 09:09:34 -0400 Subject: [PATCH 3/9] Expand version-bump scope to README and launch scripts per ReleaseProcedure.txt (#430) Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- docs/plans/Jackson-3-Migration-Plan.md | 40 ++++++++++++++++++------ docs/specs/Jackson-3-Migration-Design.md | 4 +++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/plans/Jackson-3-Migration-Plan.md b/docs/plans/Jackson-3-Migration-Plan.md index 9bd98af3..33173167 100644 --- a/docs/plans/Jackson-3-Migration-Plan.md +++ b/docs/plans/Jackson-3-Migration-Plan.md @@ -178,14 +178,18 @@ Co-Authored-By: Claude Opus 4.8 " ### Task 3: Remove Jackson 2.x dependencies and bump version to 3.0.0 -With all code on Jackson 3 and tests green, drop the now-unused 2.x deps and cut the major version. +With all code on Jackson 3 and tests green, drop the now-unused 2.x deps and cut the major version. Per `ReleaseProcedure.txt`, the version string lives in six places across five files — all must move from `2.6.4` to `3.0.0`. **Files:** -- Modify: `pom.xml` — remove two dependency blocks, change ``. +- Modify: `pom.xml` — remove two dependency blocks, change `` (1 place, line ~29). +- Modify: `README.md` — version string in 3 places (lines 17, 54, 55). +- Modify: `tester.sh` — jar name (line 2). +- Modify: `testerui.sh` — jar name (line 2). +- Modify: `testerui.cmd` — jar name (line 1). **Interfaces:** - Consumes: green build from Task 2. -- Produces: a classpath with no `com.fasterxml.jackson.core`/`databind`/`dataformat.xml` 2.x jars; project version `3.0.0`. +- Produces: a classpath with no `com.fasterxml.jackson.core`/`databind`/`dataformat.xml` 2.x jars; project version `3.0.0` consistent across pom, README, and launch scripts. - [ ] **Step 1: Remove the Jackson 2.x dependency blocks** @@ -206,26 +210,44 @@ In `pom.xml`, delete these two blocks: ``` Leave `com.fasterxml.woodstox:woodstox-core` in place — Jackson 3 XML still uses it. -- [ ] **Step 2: Bump the project version** +- [ ] **Step 2: Bump the project version in `pom.xml`** -Change the top-level project version: +Change the top-level project version (the `` directly under `JSONata4Java`, around line 29 — not a dependency or plugin version): Old: ` 2.6.4` New: ` 3.0.0` -- [ ] **Step 3: Verify no Jackson 2.x remains on the dependency tree** +- [ ] **Step 3: Bump the version string in `README.md`, `tester.sh`, `testerui.sh`, `testerui.cmd`** + +Per `ReleaseProcedure.txt`, update the version in the README (3 places) and the three launch scripts (1 each). Run from the repo root: + +```bash +perl -pi -e 's/\Q2.6.4\E/3.0.0/g' README.md tester.sh testerui.sh testerui.cmd +``` + +Verify: +```bash +grep -rn "2\.6\.4" README.md tester.sh testerui.sh testerui.cmd || echo CLEAN +``` +Expected: `CLEAN`. And confirm the new strings landed: +```bash +grep -n "3\.0\.0" README.md tester.sh testerui.sh testerui.cmd +``` +Expected: `README.md` lines 17/54/55, `tester.sh` line 2, `testerui.sh` line 2, `testerui.cmd` line 1. + +- [ ] **Step 4: Verify no Jackson 2.x remains on the dependency tree** Run: `mvn -q dependency:tree | grep "com.fasterxml.jackson" || echo NONE` Expected: only `com.fasterxml.woodstox:woodstox-core` may appear; no `com.fasterxml.jackson.core`, `...databind`, or `...dataformat.jackson-*` 2.x entries. (Note: `jackson-annotations` under `com.fasterxml.jackson` may appear transitively via Jackson 3 — that is expected and correct.) -- [ ] **Step 4: Full clean build + tests** +- [ ] **Step 5: Full clean build + tests** Run: `mvn -q clean test 2>&1 | tail -30` Expected: BUILD SUCCESS with only Jackson 3 (plus jackson-annotations 2.x, woodstox) on the classpath. -- [ ] **Step 5: Commit** +- [ ] **Step 6: Commit** ```bash -git add pom.xml +git add pom.xml README.md tester.sh testerui.sh testerui.cmd git commit -m "Drop Jackson 2.x deps, bump to 3.0.0 (#430) Co-Authored-By: Claude Opus 4.8 " diff --git a/docs/specs/Jackson-3-Migration-Design.md b/docs/specs/Jackson-3-Migration-Design.md index fa11fa7c..9e43fc1b 100644 --- a/docs/specs/Jackson-3-Migration-Design.md +++ b/docs/specs/Jackson-3-Migration-Design.md @@ -48,6 +48,10 @@ The overwhelming majority only use JSON node types whose class names are unchang | Change | `` `2.6.4` → `3.0.0` | Notes: +- **Version string lives in more than `pom.xml`.** Per `ReleaseProcedure.txt`, the release + version appears in six places across five files, all of which move `2.6.4` → `3.0.0`: + `pom.xml` (1), `README.md` (3 — lines 17, 54, 55), `tester.sh` (1), `testerui.sh` (1), + `testerui.cmd` (1). The script/README occurrences are the `JSONata4Java-...jar` names. - `jackson-core` is pulled in transitively by `jackson-databind`; no direct entry needed. - **`jackson-annotations` was NOT renamed** — it stays under `com.fasterxml.jackson.annotation`. The codebase has no annotation imports, so this is a non-issue here, but do not blindly From 1446f2c03fa285d859491694c7da7e05c1bd242a Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 10:27:21 -0400 Subject: [PATCH 4/9] Migrate from Jackson 2.x to Jackson 3 (tools.jackson) (#430) Move the codebase from com.fasterxml.jackson 2.x to tools.jackson 3.2.0. - pom.xml: use tools.jackson.core:jackson-databind and tools.jackson.dataformat:jackson-dataformat-xml 3.2.0; remove the Jackson 2.x databind and dataformat-xml deps (woodstox-core retained); bump project version 2.6.4 -> 3.0.0. - Package/class/method renames across main and test sources: com.fasterxml.jackson.* -> tools.jackson.*, TextNode -> StringNode, JsonFactory -> tools.jackson.core.json.JsonFactory, JsonProcessingException -> JacksonException, JsonMappingException -> DatabindException, immutable mapper builders. Behavior-preserving fixes for Jackson 3 default/API changes (no test assertion or expected value was changed): - MatchFunction/ReplaceFunction: guard the pattern emptiness checks so a POJONode-wrapped RegularExpression never reaches the now-throwing asText(); logic is identical to Jackson 2. - ArrayUtils.compare: pass "" default to asText() so container operands coerce to "" as they did under Jackson 2 instead of throwing. - AgnosticTestSuite: normalize whole-number doubles with (long) d, replicating Jackson 2's silent narrowing (Jackson 3's asLong() throws on out-of-long-range values). - Utils test mapper: disable FAIL_ON_TRAILING_TOKENS to restore the Jackson 2 default so existing test inputs parse identically. - catch (IOException) -> catch (JacksonException) where Jackson 3 methods no longer throw checked IOException. - README and launch scripts (tester.sh, testerui.sh, testerui.cmd): version 2.6.4 -> 3.0.0. Verified: mvn clean test green (1223 tests, 0 failures, 93 skipped); mvn package builds JSONata4Java-3.0.0.jar with an OSGi Import-Package header referencing only tools.jackson.* [3.2,4); Tester CLI evaluation and XML round-trip smoke-tested. Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- README.md | 6 +-- docs/plans/Jackson-3-Migration-Plan.md | 30 +++++++++-- pom.xml | 15 +++--- .../java/com/api/jsonata4java/Binding.java | 4 +- .../java/com/api/jsonata4java/Expression.java | 8 +-- .../com/api/jsonata4java/JSONataUtils.java | 8 +-- .../java/com/api/jsonata4java/Sequence.java | 8 +-- .../java/com/api/jsonata4java/Signature.java | 8 +-- src/main/java/com/api/jsonata4java/Test.java | 12 ++--- .../java/com/api/jsonata4java/Tester.java | 27 +++++----- .../com/api/jsonata4java/TesterTimeBox.java | 16 +++--- .../jsonata4java/expressions/Expressions.java | 2 +- .../expressions/ExpressionsVisitor.java | 48 ++++++++--------- .../expressions/FrameEnvironment.java | 4 +- .../expressions/OrderByOperator.java | 18 +++---- .../expressions/functions/AbsFunction.java | 6 +-- .../expressions/functions/AppendFunction.java | 6 +-- .../functions/AverageFunction.java | 10 ++-- .../functions/Base64DecodeFunction.java | 8 +-- .../functions/Base64EncodeFunction.java | 8 +-- .../functions/BooleanFunction.java | 6 +-- .../expressions/functions/CeilFunction.java | 6 +-- .../functions/ContainsFunction.java | 10 ++-- .../expressions/functions/CountFunction.java | 8 +-- .../functions/DeclaredFunction.java | 2 +- .../functions/DistinctFunction.java | 6 +-- .../expressions/functions/EachFunction.java | 12 ++--- .../expressions/functions/ErrorFunction.java | 4 +- .../expressions/functions/EvalFunction.java | 2 +- .../expressions/functions/ExistsFunction.java | 6 +-- .../expressions/functions/FilterFunction.java | 10 ++-- .../expressions/functions/FloorFunction.java | 6 +-- .../functions/FormatBaseFunction.java | 8 +-- .../functions/FormatNumberFunction.java | 10 ++-- .../functions/FromMillisFunction.java | 8 +-- .../functions/FromMillisZonedFunction.java | 8 +-- .../expressions/functions/FunctionBase.java | 2 +- .../functions/IndexOfFunction.java | 8 +-- .../expressions/functions/JoinFunction.java | 12 ++--- .../expressions/functions/KeysFunction.java | 14 ++--- .../expressions/functions/LengthFunction.java | 6 +-- .../expressions/functions/LookupFunction.java | 8 +-- .../functions/LowercaseFunction.java | 10 ++-- .../expressions/functions/MapFunction.java | 10 ++-- .../expressions/functions/MatchFunction.java | 12 ++--- .../expressions/functions/MaxFunction.java | 6 +-- .../expressions/functions/MergeFunction.java | 10 ++-- .../expressions/functions/MillisFunction.java | 4 +- .../expressions/functions/MinFunction.java | 6 +-- .../functions/NoContextFunction.java | 2 +- .../expressions/functions/NotFunction.java | 6 +-- .../expressions/functions/NowFunction.java | 8 +-- .../expressions/functions/NumberFunction.java | 8 +-- .../expressions/functions/PadFunction.java | 10 ++-- .../expressions/functions/PowerFunction.java | 8 +-- .../expressions/functions/RandomFunction.java | 4 +- .../expressions/functions/ReduceFunction.java | 10 ++-- .../functions/ReplaceFunction.java | 12 ++--- .../functions/ReverseFunction.java | 6 +-- .../expressions/functions/RoundFunction.java | 4 +- .../functions/ShuffleFunction.java | 6 +-- .../expressions/functions/SiftFunction.java | 16 +++--- .../expressions/functions/SortFunction.java | 6 +-- .../expressions/functions/SplitFunction.java | 8 +-- .../expressions/functions/SpreadFunction.java | 14 ++--- .../expressions/functions/SqrtFunction.java | 8 +-- .../expressions/functions/StringFunction.java | 14 ++--- .../functions/SubstringAfterFunction.java | 20 ++++---- .../functions/SubstringBeforeFunction.java | 18 +++---- .../functions/SubstringFunction.java | 8 +-- .../expressions/functions/SumFunction.java | 10 ++-- .../functions/ToMillisFunction.java | 6 +-- .../expressions/functions/TrimFunction.java | 8 +-- .../expressions/functions/TypeFunction.java | 30 +++++------ .../functions/URLDecodeComponentFunction.java | 8 +-- .../functions/URLDecodeFunction.java | 8 +-- .../functions/URLEncodeComponentFunction.java | 8 +-- .../functions/URLEncodeFunction.java | 10 ++-- .../expressions/functions/UnpackFunction.java | 4 +- .../functions/UppercaseFunction.java | 10 ++-- .../expressions/functions/ZipFunction.java | 6 +-- .../expressions/path/PathExpression.java | 2 +- .../path/PathExpressionVisitor.java | 12 ++--- .../expressions/utils/ArrayUtils.java | 19 ++++--- .../expressions/utils/BooleanUtils.java | 6 +-- .../expressions/utils/FunctionUtils.java | 10 ++-- .../expressions/utils/JsonMergeUtils.java | 8 +-- .../expressions/utils/NumberUtils.java | 6 +-- .../api/jsonata4java/testerui/TesterUI.java | 33 ++++++------ .../api/jsonata4java/AgnosticTestSuite.java | 47 +++++++++-------- .../api/jsonata4java/JsonataTimeoutTest.java | 4 +- .../expressions/BasicExpressionsTests.java | 51 ++++++++++--------- .../DiacriticsTokenizationTests.java | 2 +- .../expressions/Jsonata4JavaTestMapper.java | 8 +-- .../expressions/UnpackFunctionTests.java | 4 +- .../expressions/path/PathExpressionTests.java | 4 +- .../regex/RE2RegexPatternTest.java | 4 +- .../expressions/utils/JsonMergeUtilsTest.java | 6 +-- .../jsonata4java/expressions/utils/Utils.java | 25 +++++---- .../expressions/BasicExpressionsTests.java | 51 ++++++++++--------- .../jsonata4java/testerui/TesterUITest.java | 9 ++-- .../ExpressionTestPerformance.java | 10 ++-- .../java/testmanually/JsonataUnitTests.java | 2 +- .../testmanually/TestBindingReference.java | 10 ++-- src/test/java/testmanually/ThreadTester.java | 4 +- tester.sh | 2 +- testerui.cmd | 2 +- testerui.sh | 2 +- 108 files changed, 577 insertions(+), 542 deletions(-) diff --git a/README.md b/README.md index 987c1098..1b30975f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The easiest way to use this library is to include it as a dependency in your Mav com.ibm.jsonata4java JSONata4Java - 2.6.4 + 3.0.0 ``` @@ -51,8 +51,8 @@ Note: to build and deploy the jars to Maven Central you need to use a command li `mvn clean install deploy -Prelease` Once you have run the launcher, you can find the jar files in the /target directory. There are two: -* **JSONata4Java-2.6.4-jar-with-dependencies.jar** (thinks includes dependent jar files) -* **JSONata4Java-2.6.4.jar** (only the JSONata4Java code) +* **JSONata4Java-3.0.0-jar-with-dependencies.jar** (thinks includes dependent jar files) +* **JSONata4Java-3.0.0.jar** (only the JSONata4Java code) The com.api.jsonata4java.Tester program enables you to enter an expression and run it against the same JSON as is used at the https://try.jsonata.org site. You can also diff --git a/docs/plans/Jackson-3-Migration-Plan.md b/docs/plans/Jackson-3-Migration-Plan.md index 33173167..26b595b8 100644 --- a/docs/plans/Jackson-3-Migration-Plan.md +++ b/docs/plans/Jackson-3-Migration-Plan.md @@ -92,15 +92,39 @@ find src/main/java src/test/java -name '*.java' -print0 | xargs -0 perl -pi -e ' ' ``` +- [ ] **Step 1b: Apply Jackson 3 API class/method renames (verified against the 3.2.0 jar)** + +Jackson 3 renamed several `JsonNode` types and methods, not just packages. These were confirmed by inspecting `jackson-databind-3.2.0.jar` / `jackson-core-3.2.0.jar`: + +- `TextNode` → `StringNode` (the class `tools.jackson.databind.node.TextNode` does not exist; `StringNode` replaces it). Affects imports, `new TextNode(...)`, `TextNode.valueOf(...)`, and `(TextNode)` casts. ~106 refs. +- `tools.jackson.core.JsonProcessingException` → `tools.jackson.core.JacksonException` (JsonProcessingException is gone from core; `JacksonException` is the unchecked base). Affects imports and `catch` clauses. ~28 refs. +- `.fieldNames()` (returned `Iterator` in 2.x) → `.propertyNames()` (returns `Collection` in 3.x). To preserve `Iterator`-based loops, replace `X.fieldNames()` with `X.propertyNames().iterator()`. ~21 calls. +- `.elements()` (returned `Iterator` in 2.x) → `.values()` (returns `Collection` in 3.x). Replace `X.elements()` with `X.values().iterator()`. ~5 calls. +- `.fields()` → `.properties()` if present. (This codebase has **0** `.fields()` calls — nothing to do, but do not introduce any.) +- NOTE: `textValue()` and `asText()` **still exist** on `JsonNode` in 3.x — do NOT rewrite those. + +Apply the safe global renames with word-boundary care, then let the compiler catch the rest: + +```bash +find src/main/java src/test/java -name '*.java' -print0 | xargs -0 perl -pi -e ' + s/\bTextNode\b/StringNode/g; + s/\bJsonProcessingException\b/JacksonException/g; + s/\.fieldNames\(\)/.propertyNames().iterator()/g; + s/\.elements\(\)/.values().iterator()/g; +' +``` + +Note: `TextNode` → `StringNode` also renames the import line `import tools.jackson.databind.node.TextNode;` to `import tools.jackson.databind.node.StringNode;`, which is correct. Watch for identifiers that merely contain "TextNode" as a substring — the `\b` boundaries prevent partial-word hits, but verify at compile time. + - [ ] **Step 2: Confirm no `com.fasterxml.jackson` core/databind/xml references remain** Run: `grep -rn "com.fasterxml.jackson.core\|com.fasterxml.jackson.databind\|com.fasterxml.jackson.dataformat" src/ || echo CLEAN` Expected: `CLEAN` (annotations, if any ever appear, are intentionally left; none exist today). -- [ ] **Step 3: Compile to surface the hotspots** +- [ ] **Step 3: Compile to surface the remaining hotspots** -Run: `mvn -q -DskipTests clean compile 2>&1 | tee /tmp/j3-compile.log | tail -40` -Expected: FAILS — errors concentrated in `Tester.java` (`getFactory().configure`, `JsonWriteFeature.mappedFeature()`) and `TesterUI.java` (`xmlMapper.enable`/`.configure`, `ToXmlGenerator.Feature`). Note each reported file:line. +Run: `mvn -q -DskipTests clean compile 2>&1 | tee /tmp/j3-compile.log | grep -E "ERROR|\.java:" | head -50` +Expected: FAILS — after Step 1b the remaining errors are concentrated in `Tester.java` (`getFactory().configure`, `JsonWriteFeature.mappedFeature()`) and `TesterUI.java` (`xmlMapper.enable`/`.configure`, `ToXmlGenerator.Feature`), plus any stragglers from the method renames. Note each reported file:line and fix iteratively. - [ ] **Step 4: Fix `Tester.java` mapper construction** diff --git a/pom.xml b/pom.xml index 488700cd..a253d188 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ 4.0.0 com.ibm.jsonata4java JSONata4Java - 2.6.4 + 3.0.0 JSONata4Java Port of jsonata.js to Java to enable rules for JSON content https://github.com/IBM/JSONata4Java @@ -121,10 +121,12 @@ 3.2.0 compile + - com.fasterxml.jackson.core - jackson-databind - 2.22.0 + tools.jackson.dataformat + jackson-dataformat-xml + 3.2.0 + compile @@ -132,11 +134,6 @@ woodstox-core 7.2.1 - - com.fasterxml.jackson.dataformat - jackson-dataformat-xml - 2.22.0 - org.apache.commons diff --git a/src/main/java/com/api/jsonata4java/Binding.java b/src/main/java/com/api/jsonata4java/Binding.java index 0ae756f2..00a0e1a8 100644 --- a/src/main/java/com/api/jsonata4java/Binding.java +++ b/src/main/java/com/api/jsonata4java/Binding.java @@ -22,8 +22,8 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.NullContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.NumberContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.StringContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; /** * Class mapping a variable name to a variable or function declaration diff --git a/src/main/java/com/api/jsonata4java/Expression.java b/src/main/java/com/api/jsonata4java/Expression.java index 6adf8d48..ce6aaefd 100644 --- a/src/main/java/com/api/jsonata4java/Expression.java +++ b/src/main/java/com/api/jsonata4java/Expression.java @@ -20,9 +20,9 @@ import com.api.jsonata4java.expressions.functions.DeclaredFunction; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.ExprContext; import com.api.jsonata4java.expressions.regex.RegexEngine; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; /** * Class to provide embedding and extending JSONata features @@ -42,7 +42,7 @@ public class Expression implements Serializable { public static List createBindings(JsonNode bindingObj) throws ParseException { ObjectMapper objectMapper = new ObjectMapper(); List bindings = new ArrayList(); - for (Iterator it = bindingObj.fieldNames(); it.hasNext();) { + for (Iterator it = bindingObj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode testObj = bindingObj.get(key); String expression = ""; diff --git a/src/main/java/com/api/jsonata4java/JSONataUtils.java b/src/main/java/com/api/jsonata4java/JSONataUtils.java index 567fbbed..ca4b0969 100644 --- a/src/main/java/com/api/jsonata4java/JSONataUtils.java +++ b/src/main/java/com/api/jsonata4java/JSONataUtils.java @@ -53,10 +53,10 @@ //import java.rmi.dgc.VMID; import java.util.UUID; import javax.management.modelmbean.InvalidTargetObjectTypeException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.NullNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.NullNode; public class JSONataUtils implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/Sequence.java b/src/main/java/com/api/jsonata4java/Sequence.java index 2d244439..29ac4b10 100644 --- a/src/main/java/com/api/jsonata4java/Sequence.java +++ b/src/main/java/com/api/jsonata4java/Sequence.java @@ -24,10 +24,10 @@ import java.io.Serializable; import java.util.List; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; public class Sequence implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/Signature.java b/src/main/java/com/api/jsonata4java/Signature.java index 52dc7ed8..e2e80661 100644 --- a/src/main/java/com/api/jsonata4java/Signature.java +++ b/src/main/java/com/api/jsonata4java/Signature.java @@ -33,10 +33,10 @@ import com.api.jsonata4java.expressions.functions.DeclaredFunction; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.ExprContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.ExprListContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * Manages signature related functions diff --git a/src/main/java/com/api/jsonata4java/Test.java b/src/main/java/com/api/jsonata4java/Test.java index 3c588a5d..4048cc48 100644 --- a/src/main/java/com/api/jsonata4java/Test.java +++ b/src/main/java/com/api/jsonata4java/Test.java @@ -6,9 +6,9 @@ import com.api.jsonata4java.expressions.EvaluateRuntimeException; import com.api.jsonata4java.expressions.Expressions; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; public class Test implements Serializable { @@ -22,7 +22,7 @@ public static void main(String[] args) { String expression = "$sum(c)"; try { jsonObj = mapper.readTree(json); - } catch (IOException e1) { + } catch (JacksonException e1) { e1.printStackTrace(); } @@ -34,7 +34,7 @@ public static void main(String[] args) { System.err.println(e.getLocalizedMessage()); } catch (EvaluateRuntimeException ere) { System.err.println(ere.getLocalizedMessage()); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { e.printStackTrace(); } catch (IOException ioe) { System.err.println(ioe.getLocalizedMessage()); @@ -47,7 +47,7 @@ public static void main(String[] args) { } else { System.out.println("" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result)); } - } catch (EvaluateException | JsonProcessingException e) { + } catch (EvaluateException | JacksonException e) { System.err.println(e.getLocalizedMessage()); } } diff --git a/src/main/java/com/api/jsonata4java/Tester.java b/src/main/java/com/api/jsonata4java/Tester.java index 3309029d..27a024e1 100644 --- a/src/main/java/com/api/jsonata4java/Tester.java +++ b/src/main/java/com/api/jsonata4java/Tester.java @@ -29,11 +29,11 @@ import com.api.jsonata4java.expressions.EvaluateRuntimeException; import com.api.jsonata4java.expressions.Expressions; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.json.JsonWriteFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.core.JacksonException; +import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; /** * Expression evaluation test utility @@ -120,12 +120,13 @@ public class Tester implements Serializable { * @param args a fully qualified path and filename for test JSON could be provided */ public static void main(String[] args) { - ObjectMapper mapper = new ObjectMapper(); - mapper.getFactory().configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), true); + JsonMapper mapper = JsonMapper.builder() + .enable(JsonWriteFeature.ESCAPE_NON_ASCII) + .build(); JsonNode jsonObj = null; try { jsonObj = mapper.readTree(json); - } catch (IOException e1) { + } catch (JacksonException e1) { e1.printStackTrace(); } if (args.length > 0) { @@ -135,13 +136,11 @@ public static void main(String[] args) { System.out.println("Attempting to load JSON from file: " + args[0]); try { jsonObj = mapper.readTree(file); - } catch (JsonProcessingException e) { - System.err.println(e.getLocalizedMessage()); - } catch (IOException e) { + } catch (JacksonException e) { System.err.println(e.getLocalizedMessage()); } } else { - jsonObj = new TextNode(args[0]); + jsonObj = new StringNode(args[0]); } } else { jsonObj = null; @@ -149,7 +148,7 @@ public static void main(String[] args) { } try { System.out.println("Using json:\n" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObj)); - } catch (JsonProcessingException e1) { + } catch (JacksonException e1) { e1.printStackTrace(); } while (true) { @@ -187,7 +186,7 @@ public static void main(String[] args) { } else { System.out.println("" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result)); } - } catch (EvaluateException | JsonProcessingException e) { + } catch (EvaluateException | JacksonException e) { System.err.println(e.getLocalizedMessage()); } } diff --git a/src/main/java/com/api/jsonata4java/TesterTimeBox.java b/src/main/java/com/api/jsonata4java/TesterTimeBox.java index b995190e..7995f3b7 100644 --- a/src/main/java/com/api/jsonata4java/TesterTimeBox.java +++ b/src/main/java/com/api/jsonata4java/TesterTimeBox.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.EvaluateRuntimeException; import com.api.jsonata4java.expressions.Expressions; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; /** * Expression evaluation test utility @@ -122,7 +122,7 @@ public static void main(String[] args) { JsonNode jsonObj = null; try { jsonObj = mapper.readTree(json); - } catch (IOException e1) { + } catch (JacksonException e1) { e1.printStackTrace(); } if (args.length > 0) { @@ -130,15 +130,13 @@ public static void main(String[] args) { System.out.println("Attempting to load JSON from file: " + args[0]); try { jsonObj = mapper.readTree(file); - } catch (JsonProcessingException e) { - System.err.println(e.getLocalizedMessage()); - } catch (IOException e) { + } catch (JacksonException e) { System.err.println(e.getLocalizedMessage()); } } try { System.out.println("Using json:\n" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObj)); - } catch (JsonProcessingException e1) { + } catch (JacksonException e1) { e1.printStackTrace(); } int maxDepth = 100; @@ -205,7 +203,7 @@ public static void main(String[] args) { } else { System.out.println("" + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result)); } - } catch (EvaluateException | JsonProcessingException e) { + } catch (EvaluateException | JacksonException e) { System.err.println(e.getLocalizedMessage()); } } diff --git a/src/main/java/com/api/jsonata4java/expressions/Expressions.java b/src/main/java/com/api/jsonata4java/expressions/Expressions.java index 0f0bf5a1..ccf27c24 100644 --- a/src/main/java/com/api/jsonata4java/expressions/Expressions.java +++ b/src/main/java/com/api/jsonata4java/expressions/Expressions.java @@ -43,7 +43,7 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Expr_to_eofContext; import com.api.jsonata4java.expressions.regex.RegexEngine; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; public class Expressions implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java b/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java index b51759c4..86a42aed 100644 --- a/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java +++ b/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java @@ -75,20 +75,20 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; import com.api.jsonata4java.expressions.utils.NumberUtils; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.NumericNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.POJONode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.JsonNodeType; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.NumericNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.POJONode; +import tools.jackson.databind.node.StringNode; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; @@ -292,7 +292,7 @@ public static String castString(JsonNode node, boolean prettify) throws Evaluate } else { return objectMapper.writeValueAsString(node); } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new EvaluateRuntimeException( "Failed to cast value " + node + " to a string. Reason: " + e.getMessage()); } @@ -812,7 +812,7 @@ void traverseDescendants(JsonNode input, ArrayNode results) { traverseDescendants(member, results); } } else if (input.isObject()) { - for (Iterator it = ((ObjectNode) input).fieldNames(); it.hasNext();) { + for (Iterator it = ((ObjectNode) input).propertyNames().iterator(); it.hasNext();) { String key = it.next(); traverseDescendants(((ObjectNode) input).get(key), results); } @@ -1468,7 +1468,7 @@ public JsonNode visitConcat_op(MappingExpressionParser.Concat_opContext ctx) { } } - result = new TextNode(leftStr + rightStr); + result = new StringNode(leftStr + rightStr); lastVisited = METHOD; if (LOG.isLoggable(Level.FINEST)) { @@ -1500,7 +1500,7 @@ public JsonNode visitConditional(MappingExpressionParser.ConditionalContext ctx) } else { result = null; } - } else if (cond instanceof BooleanNode || cond instanceof NumericNode || cond instanceof TextNode) { + } else if (cond instanceof BooleanNode || cond instanceof NumericNode || cond instanceof StringNode) { ExprContext ctx1 = ctx.expr(1); ExprContext ctx2 = ctx.expr(2); if (ctx1 != null && ctx2 != null) { @@ -1731,7 +1731,7 @@ public JsonNode visitField_values(MappingExpressionParser.Field_valuesContext ct result = null; } else { if (elt.isObject()) { - for (Iterator it = ((ObjectNode) elt).fieldNames(); it.hasNext();) { + for (Iterator it = ((ObjectNode) elt).propertyNames().iterator(); it.hasNext();) { JsonNode value = ((ObjectNode) elt).get(it.next()); if (value.isArray()) { value = flatten(value, null); @@ -2050,7 +2050,7 @@ public JsonNode visitMembership(MappingExpressionParser.MembershipContext ctx) { left = unwrapArray(left); result = BooleanNode.FALSE; - Iterator elements = right.elements(); + Iterator elements = right.values().iterator(); while (elements.hasNext()) { JsonNode curElement = elements.next(); if (areJsonNodesEqual(left, curElement)) { @@ -2403,7 +2403,7 @@ public JsonNode visitObject_constructor(Object_constructorContext ctx) { visit(valueNode); fctName = ((Function_declContext) valueNode).FUNCTIONID().getText(); if (getDeclaredFunction(fctName) != null) { - value = new TextNode(""); + value = new StringNode(""); } } else if (valueNode instanceof Var_recallContext) { value = visit(valueNode); @@ -2411,11 +2411,11 @@ public JsonNode visitObject_constructor(Object_constructorContext ctx) { String varName = ((Var_recallContext) valueNode).VAR_ID().getText(); DeclaredFunction declFct = getDeclaredFunction(varName); if (declFct != null) { - value = new TextNode(""); + value = new StringNode(""); } else { FunctionBase fct = getJsonataFunction(varName); if (fct != null) { - value = new TextNode(""); + value = new StringNode(""); } else { value = null; } @@ -2739,7 +2739,7 @@ public JsonNode visitString(MappingExpressionParser.StringContext ctx) { // strip quotes and unescape any special chars val = sanitise(val); - result = TextNode.valueOf(val); + result = StringNode.valueOf(val); lastVisited = METHOD; if (LOG.isLoggable(Level.FINEST)) { LOG.exiting(CLASS, METHOD, (result == null ? "null" : result.toString())); diff --git a/src/main/java/com/api/jsonata4java/expressions/FrameEnvironment.java b/src/main/java/com/api/jsonata4java/expressions/FrameEnvironment.java index b8e404cb..5eaa8423 100644 --- a/src/main/java/com/api/jsonata4java/expressions/FrameEnvironment.java +++ b/src/main/java/com/api/jsonata4java/expressions/FrameEnvironment.java @@ -28,8 +28,8 @@ import com.api.jsonata4java.expressions.functions.DeclaredFunction; import com.api.jsonata4java.expressions.functions.FunctionBase; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; /** * {@link ExpressionsVisitor} to manage the current block's environment. diff --git a/src/main/java/com/api/jsonata4java/expressions/OrderByOperator.java b/src/main/java/com/api/jsonata4java/expressions/OrderByOperator.java index 22b44fba..df736388 100644 --- a/src/main/java/com/api/jsonata4java/expressions/OrderByOperator.java +++ b/src/main/java/com/api/jsonata4java/expressions/OrderByOperator.java @@ -9,12 +9,12 @@ import org.antlr.v4.runtime.tree.ParseTree; import com.api.jsonata4java.expressions.generated.MappingExpressionParser; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Op_orderbyContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; -import com.fasterxml.jackson.databind.node.NumericNode; -import com.fasterxml.jackson.databind.node.BooleanNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; +import tools.jackson.databind.node.NumericNode; +import tools.jackson.databind.node.BooleanNode; public class OrderByOperator { @@ -26,7 +26,7 @@ public ArrayNode evaluate(Op_orderbyContext ctx, ArrayNode in) { private ArrayNode orderBy(final ArrayNode in, final List sortFields) { final List jsonNodes = new ArrayList<>(); - final Iterator iter = in.elements(); + final Iterator iter = in.values().iterator(); while (iter.hasNext()) { jsonNodes.add(iter.next()); } @@ -38,8 +38,8 @@ public int compare(JsonNode o1, JsonNode o2) { JsonNode n1 = o1.get(sortField.name); JsonNode n2 = o2.get(sortField.name); if (n1 != null && n2 != null) { - if (n1 instanceof TextNode && n2 instanceof TextNode) { - final int comp = ((TextNode) n1).asText().compareTo(((TextNode) n2).asText()); + if (n1 instanceof StringNode && n2 instanceof StringNode) { + final int comp = ((StringNode) n1).asText().compareTo(((StringNode) n2).asText()); if (comp != 0) { return sortField.order == OrderByOrder.DESC ? comp * -1 : comp; } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/AbsFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/AbsFunction.java index 5175ef71..23bc8649 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/AbsFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/AbsFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Fct_chainContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.LongNode; /** * Returns the absolute value of the number parameter, i.e. if the number is diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/AppendFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/AppendFunction.java index b164f992..f21838e1 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/AppendFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/AppendFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.utils.ArrayUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; public class AppendFunction extends FunctionBase implements NoContextFunction { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/AverageFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/AverageFunction.java index c5d48473..1880f4a8 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/AverageFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/AverageFunction.java @@ -29,11 +29,11 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * Always returns as a DoubleNode (regardless of input) diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/Base64DecodeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/Base64DecodeFunction.java index ed60c94c..5f2432af 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/Base64DecodeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/Base64DecodeFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -92,7 +92,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex final String str = argString.textValue(); try { - result = new TextNode(new String(Base64.getDecoder().decode(str), "utf-8")); + result = new StringNode(new String(Base64.getDecoder().decode(str), "utf-8")); } catch (UnsupportedEncodingException e) { throw new EvaluateRuntimeException(ERR_RUNTIME_ERROR); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/Base64EncodeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/Base64EncodeFunction.java index 5a8e8a17..94ddcf5d 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/Base64EncodeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/Base64EncodeFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -95,7 +95,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex final String str = argString.textValue(); try { - result = new TextNode(Base64.getEncoder().encodeToString(str.getBytes("utf-8"))); + result = new StringNode(Base64.getEncoder().encodeToString(str.getBytes("utf-8"))); } catch (UnsupportedEncodingException e) { throw new EvaluateRuntimeException(ERR_RUNTIME_ERROR); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/BooleanFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/BooleanFunction.java index 655a9d89..80121423 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/BooleanFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/BooleanFunction.java @@ -30,9 +30,9 @@ import com.api.jsonata4java.expressions.utils.BooleanUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.JsonNodeFactory; /** *
From http://docs.jsonata.org/boolean-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/CeilFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/CeilFunction.java index 32150605..021e3d15 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/CeilFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/CeilFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ContainsFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ContainsFunction.java index 8531a324..01943243 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ContainsFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ContainsFunction.java @@ -28,11 +28,11 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.POJONode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.POJONode; /** * From http://docs.jsonata.org/string-functions.html: diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/CountFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/CountFunction.java index ec1397a1..4d6ce87b 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/CountFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/CountFunction.java @@ -27,10 +27,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; public class CountFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/DeclaredFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/DeclaredFunction.java index 068d3711..3912895e 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/DeclaredFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/DeclaredFunction.java @@ -38,7 +38,7 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.VarListContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; public class DeclaredFunction implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/DistinctFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/DistinctFunction.java index a09b1d1d..434b27ba 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/DistinctFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/DistinctFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.ExpressionsVisitor.SelectorArrayNode; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * From https://docs.jsonata.org/array-functions#distinct diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/EachFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/EachFunction.java index 1f20f3a1..fe71d7c8 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/EachFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/EachFunction.java @@ -36,9 +36,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * Returns an array containing the values return by the function when applied to @@ -112,7 +112,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // only send variables function can consume varCount = fctVarCount; } - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); ExprValuesContext evc = new ExprValuesContext(ctx, ctx.invokingState); @@ -144,7 +144,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } else { FunctionBase function = expressionVisitor.getJsonataFunction(varid.getText()); if (function != null) { - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); Function_callContext callCtx = new Function_callContext(ctx); @@ -173,7 +173,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // only send variables function can consume varCount = fctVarCount; } - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); ExprValuesContext evc = new ExprValuesContext(ctx, ctx.invokingState); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ErrorFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ErrorFunction.java index 7a3d8ccf..6c8d79fa 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ErrorFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ErrorFunction.java @@ -28,8 +28,8 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * From http://docs.jsonata.org/string-functions.html: diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/EvalFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/EvalFunction.java index 406d37cf..e78719d6 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/EvalFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/EvalFunction.java @@ -30,7 +30,7 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; /** * From http://docs.jsonata.org/string-functions.html: diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ExistsFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ExistsFunction.java index 280eaeb5..1f64b41f 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ExistsFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ExistsFunction.java @@ -30,9 +30,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_declContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.JsonNodeFactory; public class ExistsFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FilterFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FilterFunction.java index 009151e9..ec3e9a39 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FilterFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FilterFunction.java @@ -36,10 +36,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/higher-order-functions#filter @@ -252,7 +252,7 @@ public String getSignature() { } public void addObject(SelectorArrayNode result, ObjectNode obj) { - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); ObjectNode cell = JsonNodeFactory.instance.objectNode(); cell.set(key, obj.get(key)); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FloorFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FloorFunction.java index 77726799..cd2c1e28 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FloorFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FloorFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java index 1b570226..d21bf119 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -115,7 +115,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } // Convert the number to a string in the specified base - result = new TextNode(Integer.toString(number, radix)); + result = new StringNode(Integer.toString(number, radix)); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FormatNumberFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FormatNumberFunction.java index 3d5167da..4a2a60d8 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FormatNumberFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FormatNumberFunction.java @@ -30,9 +30,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -152,7 +152,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex formatter.setDecimalFormatSymbols(symbols); String fixedPicture = picture.replaceAll("9", "0"); formatter.applyLocalizedPattern(fixedPicture); - result = new TextNode(formatter.format(number)); + result = new StringNode(formatter.format(number)); } else { // Non-textual picture argument throw new EvaluateRuntimeException(ERR_ARG2BADTYPE); @@ -174,7 +174,7 @@ private DecimalFormatSymbols processOptionsArg(JsonNode argOptions) { DecimalFormatSymbols symbols = (DecimalFormatSymbols) Constants.DEFAULT_DECIMAL_FORMAT_SYMBOLS.clone(); // Iterate over the formatting character overrides - Iterator fieldNames = argOptions.fieldNames(); + Iterator fieldNames = argOptions.propertyNames().iterator(); while (fieldNames.hasNext()) { String fieldName = fieldNames.next(); JsonNode valueNode = argOptions.get(fieldName); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java index 3d877fff..20288a08 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -96,7 +96,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (timezone != null && timezone.isNull() == false) { timezoneStr = timezone.asText(); } - result = new TextNode(DateTimeUtils.formatDateTime(millis, pictureStr, timezoneStr)); + result = new StringNode(DateTimeUtils.formatDateTime(millis, pictureStr, timezoneStr)); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java index 3bf00e8a..3aff442d 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -96,7 +96,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (timezone != null && timezone.isNull() == false) { timezoneStr = timezone.asText(); } - result = new TextNode(DateTimeUtils.formatDateTimeFromZoneId(millis, pictureStr, timezoneStr)); + result = new StringNode(DateTimeUtils.formatDateTimeFromZoneId(millis, pictureStr, timezoneStr)); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FunctionBase.java b/src/main/java/com/api/jsonata4java/expressions/functions/FunctionBase.java index eb017750..2f2051ff 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FunctionBase.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FunctionBase.java @@ -25,7 +25,7 @@ import com.api.jsonata4java.expressions.ExpressionsVisitor; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; public abstract class FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/IndexOfFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/IndexOfFunction.java index 0afde84c..89108056 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/IndexOfFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/IndexOfFunction.java @@ -27,10 +27,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; public class IndexOfFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java index f0b13844..fe232720 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java @@ -29,10 +29,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -111,7 +111,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // Join the elements of the array argument StringJoiner stringJoiner = new StringJoiner(separator); - Iterator elements = ((ArrayNode) argArray).elements(); + Iterator elements = ((ArrayNode) argArray).values().iterator(); while (elements.hasNext()) { JsonNode element = elements.next(); if (element.isTextual()) { @@ -126,7 +126,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } // WHILE // Create the result from the joined string - result = new TextNode(stringJoiner.toString()); + result = new StringNode(stringJoiner.toString()); } else { if (argCount != 0 && argArray == null) { return null; diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/KeysFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/KeysFunction.java index 256dd246..f19c7de9 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/KeysFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/KeysFunction.java @@ -29,10 +29,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/object-functions.html @@ -82,7 +82,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex String key = ""; if (argObject.isObject()) { ObjectNode obj = (ObjectNode) argObject; - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { key = it.next(); if (result.get(key) == null) { result.put(key, true); @@ -106,7 +106,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex return null; } SelectorArrayNode output = new SelectorArrayNode(JsonNodeFactory.instance); - for (Iterator it = result.fieldNames(); it.hasNext();) { + for (Iterator it = result.propertyNames().iterator(); it.hasNext();) { output.add(it.next()); } return ExpressionsVisitor.unwrapArray(output); @@ -130,7 +130,7 @@ static void captureKeys(ObjectNode argObject, ObjectNode result) { // JsonNode value = null; String key = null; ObjectNode obj = (ObjectNode) argObject; - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { key = it.next(); if (result.get(key) == null) { result.put(key, true); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/LengthFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/LengthFunction.java index c854e189..5b2310b3 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/LengthFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/LengthFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * From http://docs.jsonata.org/string-functions.html: diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/LookupFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/LookupFunction.java index 86a145aa..6b8fac79 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/LookupFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/LookupFunction.java @@ -28,10 +28,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/object-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/LowercaseFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/LowercaseFunction.java index 9a217387..16ea415e 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/LowercaseFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/LowercaseFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -80,7 +80,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } if (argString.isTextual()) { final String str = argString.textValue(); - result = new TextNode(str.toLowerCase()); + result = new StringNode(str.toLowerCase()); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } @@ -91,7 +91,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex ParseTree value = ctx.exprValues().exprList(); result = expressionVisitor.visit(value); if (result != null && result.isTextual()) { - result = new TextNode(result.textValue().toLowerCase()); + result = new StringNode(result.textValue().toLowerCase()); } } else { throw new EvaluateRuntimeException(argCount == 0 ? ERR_BAD_CONTEXT : ERR_ARG2BADTYPE); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MapFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MapFunction.java index 0779fc13..84ad9067 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MapFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MapFunction.java @@ -36,10 +36,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/higher-order-functions#map @@ -317,7 +317,7 @@ public String getSignature() { } public void addObject(SelectorArrayNode result, ObjectNode obj) { - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); ObjectNode cell = JsonNodeFactory.instance.objectNode(); cell.set(key, obj.get(key)); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index c239f4e6..22cea7e2 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -36,11 +36,11 @@ import com.api.jsonata4java.expressions.regex.RegexPattern; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.POJONode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.POJONode; /** * From http://docs.jsonata.org/string-functions.html: @@ -103,7 +103,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } // Make sure that the pattern is a non-empty string - if (argPattern != null && (argPattern.isTextual() || argPattern instanceof POJONode) && !(argPattern.asText().isEmpty())) { + if (argPattern != null && (argPattern.isTextual() || argPattern instanceof POJONode) && !(argPattern.isTextual() && argPattern.asText().isEmpty())) { RegularExpression regex = null; if (argPattern instanceof POJONode) { regex = (RegularExpression) ((POJONode) argPattern).getPojo(); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MaxFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MaxFunction.java index 9f914ce7..f29fda3a 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MaxFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MaxFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * From http://docs.jsonata.org/aggregation-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MergeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MergeFunction.java index 48b07a27..068d70c3 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MergeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MergeFunction.java @@ -28,10 +28,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Fct_chainContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * Returns the merger of the objects in an array of objects. It is an error if @@ -94,7 +94,7 @@ private JsonNode mergeArray(final JsonNode arg) { final JsonNode obj = array.get(i); if (obj.isObject()) { ObjectNode cell = (ObjectNode) obj; - for (Iterator it = cell.fieldNames(); it.hasNext();) { + for (Iterator it = cell.propertyNames().iterator(); it.hasNext();) { final String key = it.next(); arrayResult.set(key, cell.get(key)); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MillisFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MillisFunction.java index 7ff21e63..3eca72ec 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MillisFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MillisFunction.java @@ -27,8 +27,8 @@ import com.api.jsonata4java.expressions.ExpressionsVisitor; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MinFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MinFunction.java index b71b2cfd..39f70bd6 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MinFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MinFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * From http://docs.jsonata.org/aggregation-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/NoContextFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/NoContextFunction.java index ee164cda..5eb151a4 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/NoContextFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/NoContextFunction.java @@ -1,6 +1,6 @@ package com.api.jsonata4java.expressions.functions; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; /** * Optimized version of {@link FunctionBase} where parameters don't have to be converted diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/NotFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/NotFunction.java index 1674d67a..0996988e 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/NotFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/NotFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.utils.BooleanUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.JsonNodeFactory; public class NotFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/NowFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/NowFunction.java index 8899a47a..c1c393ed 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/NowFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/NowFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -73,7 +73,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (timezone != null && timezone.isNull() == false) { timezoneStr = timezone.asText(); } - result = new TextNode(DateTimeUtils.formatDateTime(Instant.now().toEpochMilli(), pictureStr, timezoneStr)); + result = new StringNode(DateTimeUtils.formatDateTime(Instant.now().toEpochMilli(), pictureStr, timezoneStr)); return result; } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/NumberFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/NumberFunction.java index dfacca64..6308e3c5 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/NumberFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/NumberFunction.java @@ -28,10 +28,10 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; import com.api.jsonata4java.expressions.utils.NumberUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/PadFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/PadFunction.java index 148996c2..a14a1f06 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/PadFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/PadFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -118,9 +118,9 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // Generate the result.. padding to the left or right depending // on the width argument if (width < 0) { - result = new TextNode(leftPad(str, -width, padStr)); + result = new StringNode(leftPad(str, -width, padStr)); } else { - result = new TextNode(rightPad(str, width, padStr)); + result = new StringNode(rightPad(str, width, padStr)); } } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/PowerFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/PowerFunction.java index d1162aa1..6623a749 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/PowerFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/PowerFunction.java @@ -27,10 +27,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/RandomFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/RandomFunction.java index b8f2044a..615c0ca4 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/RandomFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/RandomFunction.java @@ -26,8 +26,8 @@ import com.api.jsonata4java.expressions.ExpressionsVisitor; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.DoubleNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.DoubleNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ReduceFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ReduceFunction.java index 777d3a1f..f371a5ca 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ReduceFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ReduceFunction.java @@ -36,10 +36,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/higher-order-functions#reduce @@ -227,7 +227,7 @@ public String getSignature() { } public void addObject(ArrayNode result, ObjectNode obj) { - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); ObjectNode cell = JsonNodeFactory.instance.objectNode(); cell.set(key, obj.get(key)); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java index 771f357a..4afbfb9e 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java @@ -34,10 +34,10 @@ import com.api.jsonata4java.expressions.regex.RegexPattern; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.POJONode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.POJONode; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -130,7 +130,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex int limit = -1; // Make sure that the separator is not null if (argPattern != null && (argPattern.isTextual() || argPattern instanceof POJONode)) { - if (argPattern.asText().isEmpty()) { + if (argPattern.isTextual() && argPattern.asText().isEmpty()) { throw new EvaluateRuntimeException(ERR_MSG_ARG2_EMPTY_STR); } if (argCount >= 3) { @@ -170,7 +170,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } } - result = new TextNode(replaceMatches(str, pattern, replacement, limit)); + result = new StringNode(replaceMatches(str, pattern, replacement, limit)); } else { throw new EvaluateRuntimeException(ERR_ARG3BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ReverseFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ReverseFunction.java index 816cad3b..087c1651 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ReverseFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ReverseFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; public class ReverseFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/RoundFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/RoundFunction.java index 58c394ba..d8b953d4 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/RoundFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/RoundFunction.java @@ -30,8 +30,8 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; import com.api.jsonata4java.expressions.utils.NumberUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ShuffleFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ShuffleFunction.java index bac3d4ab..4dbe2e96 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ShuffleFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ShuffleFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; public class ShuffleFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SiftFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SiftFunction.java index 7f1379f0..939180af 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SiftFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SiftFunction.java @@ -35,10 +35,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * From http://docs.jsonata.org/object-functions.html @@ -103,7 +103,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // only send variables function can consume varCount = fctVarCount; } - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); ExprValuesContext evc = new ExprValuesContext(ctx, ctx.invokingState); @@ -135,7 +135,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } else { FunctionBase function = expressionVisitor.getJsonataFunction(varid.getText()); if (function != null) { - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); Function_callContext callCtx = new Function_callContext(ctx); @@ -163,7 +163,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // only send variables function can consume varCount = fctVarCount; } - for (Iterator it = object.fieldNames(); it.hasNext();) { + for (Iterator it = object.propertyNames().iterator(); it.hasNext();) { String key = it.next(); JsonNode field = object.get(key); ExprValuesContext evc = new ExprValuesContext(ctx, ctx.invokingState); @@ -217,7 +217,7 @@ public String getSignature() { } public void addObject(ArrayNode result, ObjectNode obj) { - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); ObjectNode cell = JsonNodeFactory.instance.objectNode(); cell.set(key, obj.get(key)); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SortFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SortFunction.java index 2a57f256..f5192cde 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SortFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SortFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.utils.ArrayUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; public class SortFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SplitFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SplitFunction.java index 1c42915b..2c546480 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SplitFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SplitFunction.java @@ -30,10 +30,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.POJONode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.POJONode; /** * From http://docs.jsonata.org/string-functions.html: diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SpreadFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SpreadFunction.java index 7d7ed28c..0659a57d 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SpreadFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SpreadFunction.java @@ -31,11 +31,11 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_declContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/object-functions.html @@ -81,7 +81,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (argObject == null) { ExprContext exprCtx = ctx.exprValues().exprList().expr(0); if (exprCtx instanceof Function_declContext) { - argObject = new TextNode(""); + argObject = new StringNode(""); } } result = spread((ArrayNode) result, argObject, argIsArray); @@ -117,7 +117,7 @@ public String getSignature() { } public ArrayNode addObject(ArrayNode result, ObjectNode obj) { - for (Iterator it = obj.fieldNames(); it.hasNext();) { + for (Iterator it = obj.propertyNames().iterator(); it.hasNext();) { String key = it.next(); ObjectNode cell = JsonNodeFactory.instance.objectNode(); cell.set(key, obj.get(key)); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SqrtFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SqrtFunction.java index 82c3615d..25677185 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SqrtFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SqrtFunction.java @@ -27,10 +27,10 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/StringFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/StringFunction.java index dc9afd7a..b0d4ffa0 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/StringFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/StringFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.utils.BooleanUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -88,17 +88,17 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex arg = FunctionUtils.getValuesListExpression(expressionVisitor, ctx, 0); if (arg == null) { if (exprCtx instanceof Function_callContext || exprCtx instanceof Function_declContext) { - arg = new TextNode(""); + arg = new StringNode(""); } if (exprCtx instanceof Var_recallContext) { String varName = ((Var_recallContext) exprCtx).VAR_ID().getText(); DeclaredFunction declFct = expressionVisitor.getDeclaredFunction(varName); if (declFct != null) { - arg = new TextNode(""); + arg = new StringNode(""); } else { FunctionBase fct = expressionVisitor.getJsonataFunction(varName); if (fct != null) { - arg = new TextNode(""); + arg = new StringNode(""); } else { arg = null; } @@ -122,7 +122,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (asString == null) { result = null; } else { - result = new TextNode(asString); + result = new StringNode(asString); } } else { if (argCount == 0) { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringAfterFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringAfterFunction.java index 49b6f77f..de529f2a 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringAfterFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringAfterFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -90,17 +90,17 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex argString = FunctionUtils.getValuesListExpression(expressionVisitor, ctx, 0); if (argString == null) { if (exprCtx instanceof Function_callContext || exprCtx instanceof Function_declContext) { - argString = new TextNode(""); + argString = new StringNode(""); } if (exprCtx instanceof Var_recallContext) { String varName = ((Var_recallContext) exprCtx).VAR_ID().getText(); DeclaredFunction declFct = expressionVisitor.getDeclaredFunction(varName); if (declFct != null) { - argString = new TextNode(""); + argString = new StringNode(""); } else { FunctionBase fct = expressionVisitor.getJsonataFunction(varName); if (fct != null) { - argString = new TextNode(""); + argString = new StringNode(""); } else { argString = null; } @@ -123,7 +123,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (argChars == null) { if (argString.isTextual()) { // just return the string value of argString - return new TextNode(argString.textValue()); + return new StringNode(argString.textValue()); } else { // invalid argString throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); @@ -143,13 +143,13 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex final int index = str.indexOf(chars); if (index != -1) { if ((index + chars.length()) < str.length()) { - result = new TextNode(substr(str, index + chars.length())); + result = new StringNode(substr(str, index + chars.length())); } else { - result = new TextNode(""); + result = new StringNode(""); } } else { // argChars is not present... just return argString - result = new TextNode(str); + result = new StringNode(str); } } } else { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringBeforeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringBeforeFunction.java index adb66f04..02c326ad 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringBeforeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringBeforeFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -90,17 +90,17 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex argString = FunctionUtils.getValuesListExpression(expressionVisitor, ctx, 0); if (argString == null) { if (exprCtx instanceof Function_callContext || exprCtx instanceof Function_declContext) { - argString = new TextNode(""); + argString = new StringNode(""); } if (exprCtx instanceof Var_recallContext) { String varName = ((Var_recallContext) exprCtx).VAR_ID().getText(); DeclaredFunction declFct = expressionVisitor.getDeclaredFunction(varName); if (declFct != null) { - argString = new TextNode(""); + argString = new StringNode(""); } else { FunctionBase fct = expressionVisitor.getJsonataFunction(varName); if (fct != null) { - argString = new TextNode(""); + argString = new StringNode(""); } else { argString = null; } @@ -123,7 +123,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (argChars == null) { if (argString.isTextual()) { // just return the string value of argString - return new TextNode(argString.textValue()); + return new StringNode(argString.textValue()); } else { // invalid argString throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); @@ -142,10 +142,10 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // Find chars in str final int index = str.indexOf(chars); if (index != -1) { - result = new TextNode(substr(str, 0, index)); + result = new StringNode(substr(str, 0, index)); } else { // argChars is not present... just return argString - result = new TextNode(str); + result = new StringNode(str); } } } else { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringFunction.java index 7be406a4..db29395b 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SubstringFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SubstringFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * Complies with javascript substr (and thus JSONata $substring). See @@ -115,7 +115,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex length = null; } - result = new TextNode(JSONataUtils.substr(str, start, length)); + result = new StringNode(JSONataUtils.substr(str, start, length)); } else { throw new EvaluateRuntimeException(argCount == 0 ? ERR_ARG1BADTYPE : ERR_ARG4BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java index 148b37ca..1a6af672 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java @@ -27,11 +27,11 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; public class SumFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ToMillisFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ToMillisFunction.java index 2a603314..0e0764cb 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ToMillisFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ToMillisFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; /** * http://docs.jsonata.org/numeric-functions.html diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/TrimFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/TrimFunction.java index 030f5ff1..ac199519 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/TrimFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/TrimFunction.java @@ -27,9 +27,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -83,7 +83,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (argString != null) { if (argString.isTextual()) { final String str = argString.textValue(); - result = new TextNode(str.trim().replaceAll("\\s+", " ")); + result = new StringNode(str.trim().replaceAll("\\s+", " ")); } else { if (useContext) { throw new EvaluateRuntimeException(ERR_BAD_CONTEXT); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/TypeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/TypeFunction.java index 6b5b36b9..c16f5029 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/TypeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/TypeFunction.java @@ -32,9 +32,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -92,18 +92,18 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (exprCtxList.size() > 0) { ExprContext exprCtx = exprCtxList.get(0); if (exprCtx instanceof Function_callContext) { - result = new TextNode("function"); + result = new StringNode("function"); } else if (exprCtx instanceof Var_recallContext) { if (exprCtx.getChildCount() > 0) { String varID = exprCtx.getChild(0).getText(); // determine what this references DeclaredFunction declFct = expressionVisitor.getDeclaredFunction(varID); if (declFct != null) { - result = new TextNode("function"); + result = new StringNode("function"); } else { FunctionBase fct = expressionVisitor.getJsonataFunction(varID); if (fct != null) { - result = new TextNode("function"); + result = new StringNode("function"); } else { arg = expressionVisitor.getVariable(varID); } @@ -115,42 +115,42 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (arg != null) { switch (arg.getNodeType()) { case ARRAY: { - result = new TextNode("array"); + result = new StringNode("array"); break; } case OBJECT: { - result = new TextNode("object"); + result = new StringNode("object"); break; } case STRING: { - result = new TextNode("string"); + result = new StringNode("string"); break; } case NUMBER: { - result = new TextNode("number"); + result = new StringNode("number"); break; } case BOOLEAN: { - result = new TextNode("boolean"); + result = new StringNode("boolean"); break; } case BINARY: { break; } case NULL: { - result = new TextNode("null"); + result = new StringNode("null"); break; } case POJO: { - result = new TextNode("undefined"); + result = new StringNode("undefined"); break; } case MISSING: { - result = new TextNode("undefined"); + result = new StringNode("undefined"); break; } default: { - result = new TextNode("undefined"); + result = new StringNode("undefined"); break; } } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeComponentFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeComponentFunction.java index 8a7c199e..f58e4b56 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeComponentFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeComponentFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -90,7 +90,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } } try { - result = new TextNode(JSONataUtils.decodeURIComponent(str)); + result = new StringNode(JSONataUtils.decodeURIComponent(str)); } catch (UnsupportedEncodingException e) { throw new EvaluateRuntimeException("Malformed URL passed to " + Constants.FUNCTION_URL_DECODE_COMPONENT + ": \"" + str + "\""); } catch (IllegalArgumentException iae) { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeFunction.java index ac142595..89392a36 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/URLDecodeFunction.java @@ -29,9 +29,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -89,7 +89,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } try { - result = new TextNode(URLDecoder.decode(str, "UTF-8")); + result = new StringNode(URLDecoder.decode(str, "UTF-8")); } catch (UnsupportedEncodingException e) { throw new EvaluateRuntimeException(e.getLocalizedMessage()); } catch (IllegalArgumentException iae) { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeComponentFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeComponentFunction.java index 8f66834c..e7e8c619 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeComponentFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeComponentFunction.java @@ -30,9 +30,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -93,7 +93,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } } try { - result = new TextNode(JSONataUtils.encodeURIComponent(str)); + result = new StringNode(JSONataUtils.encodeURIComponent(str)); } catch (URISyntaxException e) { throw new EvaluateRuntimeException("Malformed URL passed to " + Constants.FUNCTION_URL_ENCODE_COMPONENT + ": \"" + str + "\""); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeFunction.java index b2687265..31184391 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/URLEncodeFunction.java @@ -31,9 +31,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -90,10 +90,10 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex int offset = str.indexOf(query); if (offset > 0) { strResult = str.substring(0, offset); - result = new TextNode(strResult + encodeURI(query)); + result = new StringNode(strResult + encodeURI(query)); } } else { - result = new TextNode(str); + result = new StringNode(str); } } catch (MalformedURLException e) { throw new EvaluateRuntimeException("Malformed URL passed to " + Constants.FUNCTION_URL_ENCODE + ": \"" + str + "\""); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/UnpackFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/UnpackFunction.java index 2a74c050..8a48f3a3 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/UnpackFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/UnpackFunction.java @@ -32,8 +32,8 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; @SuppressWarnings("unused") public class UnpackFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/UppercaseFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/UppercaseFunction.java index 8d8a859e..3278db9c 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/UppercaseFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/UppercaseFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Function_callContext; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.StringNode; /** * From http://docs.jsonata.org/string-functions.html: @@ -80,7 +80,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } if (argString.isTextual()) { final String str = argString.textValue(); - result = new TextNode(str.toUpperCase()); + result = new StringNode(str.toUpperCase()); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } @@ -91,7 +91,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex ParseTree value = ctx.exprValues().exprList(); result = expressionVisitor.visit(value); if (result != null && result.isTextual()) { - result = new TextNode(result.textValue().toUpperCase()); + result = new StringNode(result.textValue().toUpperCase()); } } else { throw new EvaluateRuntimeException(argCount == 0 ? ERR_BAD_CONTEXT : ERR_ARG2BADTYPE); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ZipFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ZipFunction.java index 9717580d..95ee6eea 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ZipFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ZipFunction.java @@ -28,9 +28,9 @@ import com.api.jsonata4java.expressions.utils.ArrayUtils; import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.FunctionUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; public class ZipFunction extends FunctionBase { diff --git a/src/main/java/com/api/jsonata4java/expressions/path/PathExpression.java b/src/main/java/com/api/jsonata4java/expressions/path/PathExpression.java index a47b77b9..096f9173 100644 --- a/src/main/java/com/api/jsonata4java/expressions/path/PathExpression.java +++ b/src/main/java/com/api/jsonata4java/expressions/path/PathExpression.java @@ -30,7 +30,7 @@ import com.api.jsonata4java.expressions.ParseException; import com.api.jsonata4java.expressions.path.generated.PathExpressionLexer; import com.api.jsonata4java.expressions.path.generated.PathExpressionParser; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; @SuppressWarnings("deprecation") public class PathExpression { diff --git a/src/main/java/com/api/jsonata4java/expressions/path/PathExpressionVisitor.java b/src/main/java/com/api/jsonata4java/expressions/path/PathExpressionVisitor.java index cb8e6616..28a42a26 100644 --- a/src/main/java/com/api/jsonata4java/expressions/path/PathExpressionVisitor.java +++ b/src/main/java/com/api/jsonata4java/expressions/path/PathExpressionVisitor.java @@ -28,10 +28,10 @@ import com.api.jsonata4java.expressions.path.generated.PathExpressionParser.Array_indexContext; import com.api.jsonata4java.expressions.path.generated.PathExpressionParser.PathContext; import com.api.jsonata4java.expressions.path.generated.PathExpressionParserBaseVisitor; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; @SuppressWarnings("unused") public abstract class PathExpressionVisitor extends PathExpressionParserBaseVisitor { @@ -109,7 +109,7 @@ public JsonNode visitPath(PathContext ctx) { // property in the schema // if this happens, use the nextNode = new ObjectNode(JsonNodeFactory.instance); - currentObject.put(fieldName, nextNode); + currentObject.set(fieldName, nextNode); } updateCurrentNodePointer(nextNode); @@ -124,7 +124,7 @@ public JsonNode visitPath(PathContext ctx) { // property in the schema // if this happens, add in an empty placeholder nextNode = new ArrayNode(JsonNodeFactory.instance); - currentObject.put(fieldName, nextNode); + currentObject.set(fieldName, nextNode); // NOTE: an out-of-bounds exception is inevitable (since there is no index that // can be in-bounds for an empty array) diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/ArrayUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/ArrayUtils.java index eb894377..8fad5839 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/ArrayUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/ArrayUtils.java @@ -24,12 +24,12 @@ import java.io.Serializable; import com.api.jsonata4java.expressions.EvaluateRuntimeException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ValueNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.JsonNodeType; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ValueNode; public class ArrayUtils implements Serializable { @@ -99,8 +99,11 @@ public static boolean compare(JsonNode left, JsonNode right) throws EvaluateRunt if (left.isTextual() && right.isTextual()) { result = left.asText().compareTo(right.asText()) > 0; } else { - ValueNode a = NumberUtils.convertNumberToValueNode(left.asText()); - ValueNode b = NumberUtils.convertNumberToValueNode(right.asText()); + // Jackson 3's no-arg asText()/asString() throws for container nodes + // (ObjectNode/ArrayNode); Jackson 2 returned "". Pass "" as the default + // to preserve the Jackson 2 coercion behavior for non-scalar operands. + ValueNode a = NumberUtils.convertNumberToValueNode(left.asText("")); + ValueNode b = NumberUtils.convertNumberToValueNode(right.asText("")); result = Double.valueOf(a.doubleValue()).compareTo(Double.valueOf(b.doubleValue())) > 0; } return result; diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java index c22a7d44..e73a8efe 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java @@ -23,8 +23,8 @@ package com.api.jsonata4java.expressions.utils; import java.io.Serializable; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ObjectNode; public class BooleanUtils implements Serializable { @@ -99,7 +99,7 @@ public static boolean convertJsonNodeToBoolean(JsonNode node) { return false; } case OBJECT: - return ((ObjectNode) node).elements().hasNext(); + return ((ObjectNode) node).values().iterator().hasNext(); case MISSING: return false; case POJO: diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/FunctionUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/FunctionUtils.java index 352aa347..6517aac8 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/FunctionUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/FunctionUtils.java @@ -61,11 +61,11 @@ import com.api.jsonata4java.expressions.generated.MappingExpressionParser.StringContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Unary_opContext; import com.api.jsonata4java.expressions.generated.MappingExpressionParser.Var_recallContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; public class FunctionUtils implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/JsonMergeUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/JsonMergeUtils.java index c3d8f1e1..da4d2f3b 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/JsonMergeUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/JsonMergeUtils.java @@ -25,10 +25,10 @@ import java.io.Serializable; import java.util.Iterator; import java.util.Map; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * A utility for merging arbitrary JSON trees. Used during default state diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java index fd8b827c..fd70d2d9 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java @@ -24,9 +24,9 @@ import java.io.Serializable; import com.api.jsonata4java.expressions.EvaluateRuntimeException; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.ValueNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.ValueNode; public class NumberUtils implements Serializable { diff --git a/src/main/java/com/api/jsonata4java/testerui/TesterUI.java b/src/main/java/com/api/jsonata4java/testerui/TesterUI.java index e5585621..9295208a 100644 --- a/src/main/java/com/api/jsonata4java/testerui/TesterUI.java +++ b/src/main/java/com/api/jsonata4java/testerui/TesterUI.java @@ -55,13 +55,13 @@ import com.api.jsonata4java.expressions.EvaluateRuntimeException; import com.api.jsonata4java.expressions.Expressions; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectWriter; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.dataformat.xml.XmlMapper; +import tools.jackson.dataformat.xml.XmlWriteFeature; /** * A Swing UI app to test JSONata4Java interactively similar to the original @@ -73,7 +73,11 @@ public class TesterUI { private Expressions expressions; private final ObjectMapper jsonMapper = new ObjectMapper(); - private final XmlMapper xmlMapper = new XmlMapper(); + private final XmlMapper xmlMapper = XmlMapper.builder() + .enable(SerializationFeature.INDENT_OUTPUT) + .enable(XmlWriteFeature.WRITE_XML_DECLARATION) + .enable(XmlWriteFeature.WRITE_XML_1_1) + .build(); private TesterUISettings settings = new TesterUISettings(); private final JMenuBar menuBar = new JMenuBar(); @@ -105,8 +109,6 @@ public class TesterUI { protected TesterUI() throws IOException { - xmlMapper.enable(SerializationFeature.INDENT_OUTPUT); - settings.load(); inputArea.setFont(settings.getFont()); @@ -313,7 +315,7 @@ private void inputToJson() { // nothing to do break; } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { e.printStackTrace(); } } @@ -361,7 +363,7 @@ private void formatInput() { .writeValueAsString(jsonMapper.readTree(inputArea.getText()))); break; } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { System.err.println("Input error: " + e.getMessage()); this.outputArea.setText("Input error: " + e.getMessage()); this.inputArea.setBackground(settings.getBackgroundError()); @@ -423,7 +425,7 @@ private void map() { inNode = jsonMapper.readTree(inputArea.getText()); break; } - } catch (JsonProcessingException | RuntimeException e) { + } catch (RuntimeException e) { System.err.println("Input error: " + e.getMessage()); this.outputArea.setText("Input error: " + e.getMessage()); this.inputArea.setBackground(settings.getBackgroundError()); @@ -456,7 +458,7 @@ public void run() { this.outputArea.setText(e.getMessage()); this.jsonataArea.setBackground(settings.getBackgroundError()); this.outputArea.setBackground(settings.getBackgroundError()); - } catch (JsonProcessingException | RuntimeException e) { + } catch (RuntimeException e) { System.err.println("JSONata mapping error: " + e.getMessage()); this.outputArea.setText("JSONata mapping error: " + e.getMessage()); this.jsonataArea.setBackground(settings.getBackgroundError()); @@ -485,9 +487,6 @@ protected static String readFile(Path filePath) throws IOException { protected String jsonToXml(final String json) throws IOException { JsonNode node = jsonMapper.readValue(json, JsonNode.class); - xmlMapper.configure(SerializationFeature.INDENT_OUTPUT, true); - xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true); - xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_1_1, true); ObjectWriter ow = xmlMapper.writer().withRootName("root"); StringWriter w = new StringWriter(); ow.writeValue(w, node); diff --git a/src/test/java/com/api/jsonata4java/AgnosticTestSuite.java b/src/test/java/com/api/jsonata4java/AgnosticTestSuite.java index 08a48f85..7b87b3f2 100644 --- a/src/test/java/com/api/jsonata4java/AgnosticTestSuite.java +++ b/src/test/java/com/api/jsonata4java/AgnosticTestSuite.java @@ -85,15 +85,16 @@ import com.api.jsonata4java.expressions.utils.JsonMergeUtils; import com.api.jsonata4java.expressions.utils.JsonMergeUtilsTest; import com.api.jsonata4java.expressions.utils.Utils; -import com.fasterxml.jackson.core.json.JsonWriteFeature; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.ObjectNode; @RunWith(AgnosticTestSuite.class) // @ExtendWith(AgnosticTestSuiteExtension.class) @@ -117,14 +118,14 @@ public class AgnosticTestSuite extends ParentRunner { "function-signatures", // #77 }); - private static final ObjectMapper _objectMapper = new ObjectMapper(); - private static final Map> SKIP_CASES = new HashMap<>(); - static { + private static final ObjectMapper _objectMapper = JsonMapper.builder() // address characters > 127 to be escaped - _objectMapper.getFactory().configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), true); + .enable(JsonWriteFeature.ESCAPE_NON_ASCII) // ensure we don't have scientific notation for numbers - _objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); - + .enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .build(); + private static final Map> SKIP_CASES = new HashMap<>(); + static { // due to unparsable use of 'in' in the tests SKIP_CASES("inclusion-operator", "case004", "case005"); // issue #43 object construction @@ -278,8 +279,9 @@ private static String readUtf8TextFile(Path path) { } private void init() throws Exception { - final ObjectMapper om = new ObjectMapper(); - om.getFactory().configure(JsonWriteFeature.ESCAPE_NON_ASCII.mappedFeature(), true); + final ObjectMapper om = JsonMapper.builder() + .enable(JsonWriteFeature.ESCAPE_NON_ASCII) + .build(); // load and parse all the dataset json files into memory System.out.println("Loading datasets"); @@ -600,7 +602,7 @@ protected void runChild(TestGroup group, RunNotifier notifier) { // introduce bindings if available String key = ""; ObjectNode bindings = testCase.getBindings(); - for (Iterator it = bindings.fieldNames(); it.hasNext();) { + for (Iterator it = bindings.propertyNames().iterator(); it.hasNext();) { key = it.next(); JsonNode value = bindings.get(key); e.getEnvironment().setVariable("$" + key, value); @@ -782,11 +784,14 @@ public TestCase(TestGroup group, String caseName, JsonNode caseJson) { if (this.expectedResult != null && this.expectedResult.isDouble()) { double d = this.expectedResult.asDouble(); if (isWholeNumber(d)) { - this.expectedResult = new LongNode(this.expectedResult.asLong()); + // Jackson 3's DoubleNode.asLong() throws on out-of-long-range + // values; Jackson 2 performed a silent narrowing cast. Replicate + // the Jackson 2 behavior so expected-value normalization is unchanged. + this.expectedResult = new LongNode((long) d); } else { // below produced to high precision and is slower // BigDecimal bd = new BigDecimal(d); - // this.expectedResult = new TextNode(bd.toPlainString()); + // this.expectedResult = new StringNode(bd.toPlainString()); } } } else { @@ -816,7 +821,7 @@ public TestCase(TestGroup group, String caseName, JsonNode caseJson) { ObjectNode bindings = (ObjectNode) bindTest; // are there keys to be bound as variables to their content? String varID = ""; - for (Iterator it = bindings.fieldNames(); it.hasNext();) { + for (Iterator it = bindings.propertyNames().iterator(); it.hasNext();) { varID = it.next(); this.bindings.set(varID, bindings.get(varID)); } diff --git a/src/test/java/com/api/jsonata4java/JsonataTimeoutTest.java b/src/test/java/com/api/jsonata4java/JsonataTimeoutTest.java index 7cbe5c91..73488d5d 100644 --- a/src/test/java/com/api/jsonata4java/JsonataTimeoutTest.java +++ b/src/test/java/com/api/jsonata4java/JsonataTimeoutTest.java @@ -3,8 +3,8 @@ import org.junit.Test; import org.junit.Assert; import com.api.jsonata4java.expressions.Expressions; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; public class JsonataTimeoutTest { // issue 245 diff --git a/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java b/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java index 435d7b3a..76005f30 100644 --- a/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java @@ -43,19 +43,20 @@ import com.api.jsonata4java.expressions.functions.ShuffleFunction; import com.api.jsonata4java.expressions.functions.SubstringFunction; import com.api.jsonata4java.expressions.functions.SumFunction; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.FloatNode; -import com.fasterxml.jackson.databind.node.IntNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.FloatNode; +import tools.jackson.databind.node.IntNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.JsonNodeType; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; /** * A collection of poorly-structured test cases. Don't add new tests to this @@ -217,7 +218,7 @@ public class BasicExpressionsTests implements Serializable { jsonObj2 = mapper.readTree(json2); jsonObj3 = mapper.readTree(json3); jsonObj4 = mapper.readTree(json4); - } catch (IOException e) { + } catch (JacksonException e) { e.printStackTrace(); } } @@ -1316,7 +1317,7 @@ public void testConditionalLazyEval() throws ParseException, EvaluateException, event.set("t", new FloatNode(-42)); ObjectNode state = mapper.createObjectNode(); - state.set("temperatureStatus", new TextNode("hot")); + state.set("temperatureStatus", new StringNode("hot")); JsonNode result = expression.evaluate(event); @@ -1338,7 +1339,7 @@ public void testConditionalLazyEval() throws ParseException, EvaluateException, @Test public void testNullEquality() throws Exception { ObjectNode event = mapper.createObjectNode(); - event.put("asdsad", NullNode.getInstance()); + event.set("asdsad", NullNode.getInstance()); { Expressions expression = Expressions.parse("asdsad=\"null\""); Assert.assertEquals(BooleanNode.FALSE, expression.evaluate(event)); @@ -1369,10 +1370,10 @@ public void testNullEquality() throws Exception { // @Test // public void test(){ - // Assert.assertTrue( new TextNode("true").asBoolean() ); - // Assert.assertFalse( new TextNode("false").asBoolean() ); - // Assert.assertFalse( new TextNode("T").asBoolean() ); - // Assert.assertFalse( new TextNode("H").asBoolean() ); + // Assert.assertTrue( new StringNode("true").asBoolean() ); + // Assert.assertFalse( new StringNode("false").asBoolean() ); + // Assert.assertFalse( new StringNode("T").asBoolean() ); + // Assert.assertFalse( new StringNode("H").asBoolean() ); // // Assert.assertTrue( new IntNode(1).asBoolean() ); // Assert.assertFalse( new IntNode(0).asBoolean() ); @@ -1388,7 +1389,7 @@ public void testNullComparison() throws Exception { }; ObjectNode event = mapper.createObjectNode(); - event.put("isnull", NullNode.getInstance()); + event.set("isnull", NullNode.getInstance()); for (String op : ops) { try { @@ -1426,7 +1427,7 @@ public void testExistsFunction() throws Exception { // set to *java* null (not NullNode singleton) try { ObjectNode event = mapper.createObjectNode(); - event.put("notset", (ObjectNode) null); + event.set("notset", (ObjectNode) null); Expressions.parse("notset").evaluate(event); } catch (EvaluateException ex) { Assert.assertEquals("The property 'notset' does not exist", ex.getMessage()); @@ -1456,10 +1457,10 @@ public void testExistsFunction() throws Exception { // http://try.jsonata.org/ for (JsonNode valueType : new JsonNode[] { NullNode.getInstance(), new IntNode(22), BooleanNode.TRUE, - new LongNode(22L), new TextNode("true"), new IntNode(0), BooleanNode.FALSE, new LongNode(0), - new TextNode("false"), new TextNode("22") + new LongNode(22L), new StringNode("true"), new IntNode(0), BooleanNode.FALSE, new LongNode(0), + new StringNode("false"), new StringNode("22") }) { - event.put("foo", valueType); + event.set("foo", valueType); Assert.assertEquals(BooleanNode.TRUE, Expressions.parse("$exists(foo)").evaluate(event)); } } diff --git a/src/test/java/com/api/jsonata4java/expressions/DiacriticsTokenizationTests.java b/src/test/java/com/api/jsonata4java/expressions/DiacriticsTokenizationTests.java index ea46c4f9..d677debe 100644 --- a/src/test/java/com/api/jsonata4java/expressions/DiacriticsTokenizationTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/DiacriticsTokenizationTests.java @@ -31,7 +31,7 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import com.api.jsonata4java.expressions.utils.Utils; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; /** * Allow "any kind of letter from any language" instead of [a-zA-Z] in jsonata expressions diff --git a/src/test/java/com/api/jsonata4java/expressions/Jsonata4JavaTestMapper.java b/src/test/java/com/api/jsonata4java/expressions/Jsonata4JavaTestMapper.java index 765319e3..d6b9029f 100644 --- a/src/test/java/com/api/jsonata4java/expressions/Jsonata4JavaTestMapper.java +++ b/src/test/java/com/api/jsonata4java/expressions/Jsonata4JavaTestMapper.java @@ -3,9 +3,9 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; public class Jsonata4JavaTestMapper { @@ -37,7 +37,7 @@ public String map(final String in, final boolean beautify) { } else { return mapper.writeValueAsString(outputRootNode); } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } } diff --git a/src/test/java/com/api/jsonata4java/expressions/UnpackFunctionTests.java b/src/test/java/com/api/jsonata4java/expressions/UnpackFunctionTests.java index 9fe7fc30..dc8e1c38 100644 --- a/src/test/java/com/api/jsonata4java/expressions/UnpackFunctionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/UnpackFunctionTests.java @@ -32,8 +32,8 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import com.api.jsonata4java.expressions.functions.UnpackFunction; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; /** * For simplicity, these tests don't rely on $state/$event/$instance access; diff --git a/src/test/java/com/api/jsonata4java/expressions/path/PathExpressionTests.java b/src/test/java/com/api/jsonata4java/expressions/path/PathExpressionTests.java index 2d54b9dd..0182d461 100644 --- a/src/test/java/com/api/jsonata4java/expressions/path/PathExpressionTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/path/PathExpressionTests.java @@ -32,8 +32,8 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import com.api.jsonata4java.expressions.EvaluateRuntimeException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; @RunWith(Parameterized.class) public class PathExpressionTests implements Serializable { diff --git a/src/test/java/com/api/jsonata4java/expressions/regex/RE2RegexPatternTest.java b/src/test/java/com/api/jsonata4java/expressions/regex/RE2RegexPatternTest.java index de1768fc..13390acb 100644 --- a/src/test/java/com/api/jsonata4java/expressions/regex/RE2RegexPatternTest.java +++ b/src/test/java/com/api/jsonata4java/expressions/regex/RE2RegexPatternTest.java @@ -29,8 +29,8 @@ import com.api.jsonata4java.Expression; import com.api.jsonata4java.expressions.EvaluateException; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.junit.Test; /** diff --git a/src/test/java/com/api/jsonata4java/expressions/utils/JsonMergeUtilsTest.java b/src/test/java/com/api/jsonata4java/expressions/utils/JsonMergeUtilsTest.java index e3fe623d..d91786f3 100644 --- a/src/test/java/com/api/jsonata4java/expressions/utils/JsonMergeUtilsTest.java +++ b/src/test/java/com/api/jsonata4java/expressions/utils/JsonMergeUtilsTest.java @@ -33,8 +33,8 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; /** * Runs the test cases defined in src/test/resources/JsonMergeUtilsTest.json @@ -81,7 +81,7 @@ public void testCase() throws Exception { } - // public static JsonNode merge(String x, String y) throws JsonProcessingException, IOException { + // public static JsonNode merge(String x, String y) throws JacksonException, IOException { // return merge(, OM.readTree(y)); // } // diff --git a/src/test/java/com/api/jsonata4java/expressions/utils/Utils.java b/src/test/java/com/api/jsonata4java/expressions/utils/Utils.java index 446a56db..394e2cd9 100644 --- a/src/test/java/com/api/jsonata4java/expressions/utils/Utils.java +++ b/src/test/java/com/api/jsonata4java/expressions/utils/Utils.java @@ -35,13 +35,15 @@ import com.api.jsonata4java.expressions.EvaluateException; import com.api.jsonata4java.expressions.Expressions; import com.api.jsonata4java.expressions.ParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.ObjectNode; public class Utils implements Serializable { @@ -70,12 +72,17 @@ public static String generateOrgId() { return new String(buf); } - public static JsonNode getJson(String filePath) throws JsonProcessingException, IOException { + public static JsonNode getJson(String filePath) throws JacksonException, IOException { ObjectMapper m = new ObjectMapper(); return m.readTree(new File(filePath)); } - public static final ObjectMapper mapper = new ObjectMapper(); + // Jackson 3 flipped FAIL_ON_TRAILING_TOKENS to true by default; Jackson 2 + // silently ignored content after the first parsed value. Restore the + // Jackson 2 default so existing test inputs parse identically. + public static final ObjectMapper mapper = JsonMapper.builder() + .disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) + .build(); public static void simpleTest(String expression, String expected) throws Exception { test(expression, expected, null, null); diff --git a/src/test/java/com/api/jsonata4java/test/expressions/BasicExpressionsTests.java b/src/test/java/com/api/jsonata4java/test/expressions/BasicExpressionsTests.java index f69e81d9..148a5fe4 100644 --- a/src/test/java/com/api/jsonata4java/test/expressions/BasicExpressionsTests.java +++ b/src/test/java/com/api/jsonata4java/test/expressions/BasicExpressionsTests.java @@ -48,19 +48,20 @@ import com.api.jsonata4java.expressions.functions.ShuffleFunction; import com.api.jsonata4java.expressions.functions.SubstringFunction; import com.api.jsonata4java.expressions.functions.SumFunction; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.DoubleNode; -import com.fasterxml.jackson.databind.node.FloatNode; -import com.fasterxml.jackson.databind.node.IntNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.JsonNodeType; -import com.fasterxml.jackson.databind.node.LongNode; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BooleanNode; +import tools.jackson.databind.node.DoubleNode; +import tools.jackson.databind.node.FloatNode; +import tools.jackson.databind.node.IntNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.JsonNodeType; +import tools.jackson.databind.node.LongNode; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; /** * A collection of poorly-structured test cases. Don't add new tests to this @@ -214,7 +215,7 @@ public class BasicExpressionsTests implements Serializable { jsonObj = mapper.readTree(json); jsonObj2 = mapper.readTree(json2); jsonObj3 = mapper.readTree(json3); - } catch (IOException e) { + } catch (JacksonException e) { e.printStackTrace(); } } @@ -1351,7 +1352,7 @@ public void testConditionalLazyEval() throws ParseException, EvaluateException, event.set("t", new FloatNode(-42)); ObjectNode state = mapper.createObjectNode(); - state.set("temperatureStatus", new TextNode("hot")); + state.set("temperatureStatus", new StringNode("hot")); JsonNode result = expression.evaluate(event); @@ -1373,7 +1374,7 @@ public void testConditionalLazyEval() throws ParseException, EvaluateException, @Test public void testNullEquality() throws Exception { ObjectNode event = mapper.createObjectNode(); - event.put("asdsad", NullNode.getInstance()); + event.set("asdsad", NullNode.getInstance()); { Expressions expression = Expressions.parse("asdsad=\"null\""); Assert.assertEquals(BooleanNode.FALSE, expression.evaluate(event)); @@ -1404,10 +1405,10 @@ public void testNullEquality() throws Exception { // @Test // public void test(){ - // Assert.assertTrue( new TextNode("true").asBoolean() ); - // Assert.assertFalse( new TextNode("false").asBoolean() ); - // Assert.assertFalse( new TextNode("T").asBoolean() ); - // Assert.assertFalse( new TextNode("H").asBoolean() ); + // Assert.assertTrue( new StringNode("true").asBoolean() ); + // Assert.assertFalse( new StringNode("false").asBoolean() ); + // Assert.assertFalse( new StringNode("T").asBoolean() ); + // Assert.assertFalse( new StringNode("H").asBoolean() ); // // Assert.assertTrue( new IntNode(1).asBoolean() ); // Assert.assertFalse( new IntNode(0).asBoolean() ); @@ -1423,7 +1424,7 @@ public void testNullComparison() throws Exception { }; ObjectNode event = mapper.createObjectNode(); - event.put("isnull", NullNode.getInstance()); + event.set("isnull", NullNode.getInstance()); for (String op : ops) { try { @@ -1461,7 +1462,7 @@ public void testExistsFunction() throws Exception { // set to *java* null (not NullNode singleton) try { ObjectNode event = mapper.createObjectNode(); - event.put("notset", (ObjectNode) null); + event.set("notset", (ObjectNode) null); Expressions.parse("notset").evaluate(event); } catch (EvaluateException ex) { Assert.assertEquals("The property 'notset' does not exist", ex.getMessage()); @@ -1491,10 +1492,10 @@ public void testExistsFunction() throws Exception { // http://try.jsonata.org/ for (JsonNode valueType : new JsonNode[] { NullNode.getInstance(), new IntNode(22), BooleanNode.TRUE, - new LongNode(22L), new TextNode("true"), new IntNode(0), BooleanNode.FALSE, new LongNode(0), - new TextNode("false"), new TextNode("22") + new LongNode(22L), new StringNode("true"), new IntNode(0), BooleanNode.FALSE, new LongNode(0), + new StringNode("false"), new StringNode("22") }) { - event.put("foo", valueType); + event.set("foo", valueType); Assert.assertEquals(BooleanNode.TRUE, Expressions.parse("$exists(foo)").evaluate(event)); } } diff --git a/src/test/java/com/api/jsonata4java/testerui/TesterUITest.java b/src/test/java/com/api/jsonata4java/testerui/TesterUITest.java index ac720021..082b1fb9 100644 --- a/src/test/java/com/api/jsonata4java/testerui/TesterUITest.java +++ b/src/test/java/com/api/jsonata4java/testerui/TesterUITest.java @@ -6,9 +6,10 @@ import java.nio.file.Paths; import org.junit.Before; import org.junit.Test; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; +import tools.jackson.core.JacksonException; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; public class TesterUITest { @@ -40,7 +41,7 @@ public static String minifyJson(final String in) { while (parser.nextToken() != null) { gen.copyCurrentEvent(parser); } - } catch (IOException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } return sw.getBuffer().toString(); diff --git a/src/test/java/testmanually/ExpressionTestPerformance.java b/src/test/java/testmanually/ExpressionTestPerformance.java index be698a7b..b2acdb19 100644 --- a/src/test/java/testmanually/ExpressionTestPerformance.java +++ b/src/test/java/testmanually/ExpressionTestPerformance.java @@ -24,10 +24,10 @@ import org.junit.Test; import com.api.jsonata4java.expressions.Jsonata4JavaTestMapper; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; /** * Performance test for big expressions. @@ -95,7 +95,7 @@ public void testWithBigInput_withParentPath() throws Exception { System.out.println("END: mapping, took " + (System.currentTimeMillis() - startMillis) + " ms"); } - private JsonNode generateBigJson() throws JsonProcessingException, JsonMappingException { + private JsonNode generateBigJson() throws JacksonException, DatabindException { StringBuilder sb = new StringBuilder(); sb.append("{\"list\":["); for (int i = 0; i < 2500000; i++) { diff --git a/src/test/java/testmanually/JsonataUnitTests.java b/src/test/java/testmanually/JsonataUnitTests.java index 45cb2053..0473fefe 100644 --- a/src/test/java/testmanually/JsonataUnitTests.java +++ b/src/test/java/testmanually/JsonataUnitTests.java @@ -31,7 +31,7 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; /** * Verify behavior when access special $state, $event and $instance variables. diff --git a/src/test/java/testmanually/TestBindingReference.java b/src/test/java/testmanually/TestBindingReference.java index 36c4bbec..0857a25a 100644 --- a/src/test/java/testmanually/TestBindingReference.java +++ b/src/test/java/testmanually/TestBindingReference.java @@ -7,10 +7,10 @@ import org.junit.Test; import com.api.jsonata4java.Binding; import com.api.jsonata4java.Expression; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.IntNode; -import com.fasterxml.jackson.databind.node.TextNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.IntNode; +import tools.jackson.databind.node.StringNode; public class TestBindingReference implements Serializable { @@ -68,7 +68,7 @@ public void supportsContextualizedConstruction() throws Exception { bindingList.add(bindingNode); JsonNode actual = jsonataExpr.evaluate(rootContextNode, bindingList); - JsonNode expected = new TextNode("bar"); + JsonNode expected = new StringNode("bar"); Assert.assertEquals(expected, actual); json = "{\"bar\": [ 4, 5, 6]}"; diff --git a/src/test/java/testmanually/ThreadTester.java b/src/test/java/testmanually/ThreadTester.java index 7d2bb07d..74fa3881 100644 --- a/src/test/java/testmanually/ThreadTester.java +++ b/src/test/java/testmanually/ThreadTester.java @@ -4,8 +4,8 @@ import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskExecutor; import com.api.jsonata4java.expressions.Expressions; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; public class ThreadTester { diff --git a/tester.sh b/tester.sh index 4874a846..bc4ef998 100755 --- a/tester.sh +++ b/tester.sh @@ -1,2 +1,2 @@ #! /bin/bash -java -cp target/JSONata4Java-2.6.4-jar-with-dependencies.jar com.api.jsonata4java.Tester $1 +java -cp target/JSONata4Java-3.0.0-jar-with-dependencies.jar com.api.jsonata4java.Tester $1 diff --git a/testerui.cmd b/testerui.cmd index 6196055c..a46ec9ad 100644 --- a/testerui.cmd +++ b/testerui.cmd @@ -1 +1 @@ -java -cp target/JSONata4Java-2.6.4-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI +java -cp target/JSONata4Java-3.0.0-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI diff --git a/testerui.sh b/testerui.sh index 66d4f06b..e88b778d 100755 --- a/testerui.sh +++ b/testerui.sh @@ -1,2 +1,2 @@ #! /bin/bash -java -cp target/JSONata4Java-2.6.4-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI +java -cp target/JSONata4Java-3.0.0-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI From 7888c8b9fe4da47c1726d263b6b00707c151420f Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 12:09:01 -0400 Subject: [PATCH 5/9] Document retained Jackson 2 behaviors and known issues (#430) - Add a "Retained Jackson 2 behaviors (as-built)" section to the design spec listing each compatibility decision (container asText(""), POJONode emptiness guards, (long) d narrowing, FAIL_ON_TRAILING_TOKENS, unchecked-exception catches), plus the pre-existing Tester EOF NPE and the acceptable transitive jackson-annotations dependency. - Add explanatory comments at the MatchFunction/ReplaceFunction guard sites so the isTextual()-guarded emptiness checks are self-documenting. Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- docs/specs/Jackson-3-Migration-Design.md | 40 +++++++++++++++++++ .../expressions/functions/MatchFunction.java | 7 +++- .../functions/ReplaceFunction.java | 6 +++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/docs/specs/Jackson-3-Migration-Design.md b/docs/specs/Jackson-3-Migration-Design.md index 9e43fc1b..c0e5baeb 100644 --- a/docs/specs/Jackson-3-Migration-Design.md +++ b/docs/specs/Jackson-3-Migration-Design.md @@ -144,3 +144,43 @@ becomes unreachable, or the type is no longer resolvable, replace with `configure(feature, boolean)` shape. - **`new ObjectMapper()` availability** — if the no-arg constructor is unavailable/discouraged in 3.x, fall back to `JsonMapper.shared()` or `new JsonMapper()`. + +## Retained Jackson 2 behaviors (as-built) + +Jackson 3 tightened several coercion/parse defaults that would otherwise change observable +behavior. Each site below was fixed to **preserve the Jackson 2 behavior** — no test assertion or +expected value was changed. These are the compatibility decisions a future maintainer should know +about (and can revisit if the project decides to adopt the stricter Jackson 3 semantics): + +- **Container coercion — `ArrayUtils.compare` (main).** Jackson 3's no-arg `asText()`/`asString()` + throws for container nodes (`ObjectNode`/`ArrayNode`); Jackson 2 returned `""`. Fixed by passing + the default: `asText("")`. `$sort` on non-scalar operands therefore coerces to `""` exactly as + before instead of throwing. +- **Regex `POJONode` emptiness checks — `MatchFunction`, `ReplaceFunction` (main).** A compiled + `RegularExpression` is stored in a `POJONode`. Jackson 2's `asText()` returned the POJO's + `toString()` (non-empty); Jackson 3 throws for a `POJONode`. The empty-pattern checks are now + guarded by `isTextual()` so the throwing call is never reached for a `POJONode`, while the + boolean outcome is identical to Jackson 2. +- **Out-of-range `asLong()` — `AgnosticTestSuite` (test harness).** Jackson 3's `DoubleNode.asLong()` + throws when the value is outside `long` range (e.g. `1.0E46`); Jackson 2 performed a silent + narrowing cast. Expected-value normalization now uses `(long) d`, replicating Jackson 2 exactly. +- **`FAIL_ON_TRAILING_TOKENS` — `Utils` test mapper (test harness).** Jackson 3 flips this default + to `true`; Jackson 2 silently ignored content after the first parsed value. The shared test + mapper disables the feature so existing test inputs parse identically. Note: this tolerates a + long-standing typo in a test input (`BasicExpressionsTests`, `"[\"h11\", \"h21\"]]"` — a stray + trailing `]`). The typo was intentionally **not** corrected, to keep the test data byte-for-byte + unchanged. +- **Unchecked exceptions — several files.** Where Jackson 3 methods no longer throw checked + `IOException`, `catch (IOException)` blocks over Jackson-only bodies became unreachable and were + changed to `catch (JacksonException)`. + +### Other known items (not changed by this migration) + +- **Pre-existing `Tester` REPL NPE.** `Tester.main` (`Tester.java:156`) calls + `expression.length()` without a null check; `JSONataUtils.prompt()` returns `null` at stdin EOF, + causing a `NullPointerException` when input ends without a `q` line. This predates the migration + (authored 2022) and was left as-is. +- **Transitive `jackson-annotations` 2.x.** `tools.jackson.core:jackson-databind:3.2.0` still pulls + in `com.fasterxml.jackson.core:jackson-annotations` — Jackson 3 continues to publish annotations + under the `com.fasterxml.jackson.annotation` namespace. This is expected and acceptable; it is not + a leftover Jackson 2 core/databind/dataformat dependency. diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java index 22cea7e2..a1406c37 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/MatchFunction.java @@ -102,7 +102,12 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (argString == null || !argString.isTextual() || argString.asText().isEmpty()) { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } - // Make sure that the pattern is a non-empty string + // Make sure that the pattern is a non-empty string. + // The emptiness check is guarded by isTextual() because a POJONode + // wraps a compiled RegularExpression (inherently non-empty): under + // Jackson 2 asText() returned the POJO's toString(), but Jackson 3's + // asText()/asString() throws for a POJONode. Skipping the check for + // non-textual nodes keeps the original behavior without that throw. if (argPattern != null && (argPattern.isTextual() || argPattern instanceof POJONode) && !(argPattern.isTextual() && argPattern.asText().isEmpty())) { RegularExpression regex = null; if (argPattern instanceof POJONode) { diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java index 4afbfb9e..9f84c2a4 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/ReplaceFunction.java @@ -130,6 +130,12 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex int limit = -1; // Make sure that the separator is not null if (argPattern != null && (argPattern.isTextual() || argPattern instanceof POJONode)) { + // The empty-string rejection only applies to textual patterns. + // A POJONode wraps a compiled RegularExpression (inherently + // non-empty); under Jackson 2 asText() returned the POJO's + // toString(), but Jackson 3's asText()/asString() throws for a + // POJONode, so the isTextual() guard preserves the original + // behavior without triggering that throw. if (argPattern.isTextual() && argPattern.asText().isEmpty()) { throw new EvaluateRuntimeException(ERR_MSG_ARG2_EMPTY_STR); } From b9828b4c8d00fa6593acc50551f983908a2a9337 Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 16:23:45 -0400 Subject: [PATCH 6/9] Fix out-of-range numeric coercion and related Jackson 3 fail-fast crashes (#433) Jackson 3 makes asInt()/asLong()/textValue()/asBoolean() fail-fast: they throw JsonNodeException for out-of-range or wrong-type nodes where Jackson 2 silently narrowed/coerced. Several unchanged call sites therefore flipped from "return a value" to "crash with a raw Jackson exception". Fix them to use the widest-safe representation (BigInteger/double) or a controlled JSONata error, matching jsonata.org 2.2.1 where known. #433 numeric coercion: - ExpressionsVisitor.isWholeNumber(JsonNode): use the double overload instead of asInt()==asDouble() (threw for integral doubles > int range, e.g. 1e19). - Array index: only select when canConvertToInt(); out-of-int-range indices are out of bounds and select nothing (e.g. ["a","b"][3000000000] -> undefined). - Range visitSeq: compute bounds and size with BigInteger, raising the controlled "sequence too big" error for [1..1e19]/[1..3000000000] (also fixes a latent int count overflow). - Unary minus: negate an out-of-long-range BigIntegerNode exactly. - Equality (=) and ordering (< > <= >=): compare integral operands via exact bigIntegerValue(), hardening the same crash class on BigInteger operands. - SumFunction: oversized integral elements fall back to the double-sum path. - FromMillis/FromMillisZoned: convert an out-of-range magnitude to a controlled "Number out of range" error while preserving fractional-millis truncation. - FormatBase: use the full long value + Long.toString instead of a 32-bit int ($formatBase(5890840712243076) -> "5890840712243076", was "1008002948"). Related migration compatibility fixes swept in: - JoinFunction (#434): every element must be a string; error on any non-string (including nested arrays) instead of flattening, matching the reference and avoiding textValue() throwing. - BooleanUtils: return false for a BinaryNode (JSON/reference has no binary type; Jackson 3's no-arg asBoolean() throws) consistent with prior behavior. - Ordering operators: array/object operands raise "must evaluate to numeric or string values" rather than returning null. Adds BasicExpressionsTests.testOutOfRangeNumericCoercion documenting the fixed behavior. Full suite: 1223 run, 0 failures, 0 errors, 93 skipped. Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- .../expressions/ExpressionsVisitor.java | 135 ++++++++++++------ .../functions/FormatBaseFunction.java | 7 +- .../functions/FromMillisFunction.java | 13 +- .../functions/FromMillisZonedFunction.java | 13 +- .../expressions/functions/JoinFunction.java | 13 +- .../expressions/functions/SumFunction.java | 12 +- .../expressions/utils/BooleanUtils.java | 7 +- .../expressions/BasicExpressionsTests.java | 130 +++++++++++++++++ 8 files changed, 277 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java b/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java index 86a42aed..fb8ea3b5 100644 --- a/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java +++ b/src/main/java/com/api/jsonata4java/expressions/ExpressionsVisitor.java @@ -24,6 +24,7 @@ import java.io.Serializable; import java.math.BigDecimal; +import java.math.BigInteger; import java.math.MathContext; import java.text.DecimalFormat; import java.util.ArrayList; @@ -79,6 +80,7 @@ import tools.jackson.databind.JsonNode; import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BigIntegerNode; import tools.jackson.databind.node.BooleanNode; import tools.jackson.databind.node.DoubleNode; import tools.jackson.databind.node.JsonNodeFactory; @@ -167,14 +169,25 @@ public List getSelectionGroups() { * @return */ private static boolean areJsonNodesEqual(JsonNode left, JsonNode right) { - if (left.isFloatingPointNumber() || right.isFloatingPointNumber()) { + // Only coerce to double when BOTH operands are numbers. In JSONata, + // equality across different types is simply false (e.g. 3.14 in + // ["abc"] is false, matching jsonata.org), so a number-vs-string pair + // must fall through to the final "return false" rather than attempt a + // numeric coercion. This also avoids Jackson 3's asDouble() throwing + // for a non-numeric StringNode (Jackson 2 returned 0.0). The "=" / "in" + // operators only ever reach the number branches with two numbers, so + // adding the isNumber() guards does not change any equal-type result. + if ((left.isFloatingPointNumber() || right.isFloatingPointNumber()) && left.isNumber() && right.isNumber()) { return (left.asDouble() == right.asDouble()); - } else if (left.isDouble() || right.isDouble()) { + } else if ((left.isDouble() || right.isDouble()) && left.isNumber() && right.isNumber()) { return (left.asDouble() == right.asDouble()); } else if (left.isIntegralNumber() && right.isIntegralNumber()) { - return left.asLong() == right.asLong(); + // Compare exactly via BigInteger: asLong() throws under Jackson 3 for a + // data-sourced BigIntegerNode outside long range, and would otherwise + // collide distinct huge integers that share their low 64 bits. + return left.bigIntegerValue().equals(right.bigIntegerValue()); } else if (left.isLong() && right.isLong()) { - return left.asLong() == right.asLong(); + return left.bigIntegerValue().equals(right.bigIntegerValue()); } else if (left.isNull()) { return right.isNull(); } else if (right.isNull()) { @@ -378,8 +391,12 @@ private static boolean isWholeNumber(JsonNode n) { return false; } else if (n.isInt() || n.isLong()) { return true; - } else if ((n.isFloat() || n.isDouble()) && (n.asInt() == n.asDouble())) { - return true; + } else if (n.isFloat() || n.isDouble()) { + // Delegate to the double overload rather than comparing n.asInt() to + // n.asDouble(): under Jackson 3, asInt() throws for an integral-valued + // double outside int range (e.g. 1e19), and the old comparison also + // wrongly reported such values as non-whole. doubleValue() never throws. + return isWholeNumber(n.doubleValue()); } else { return false; } @@ -991,7 +1008,13 @@ public JsonNode visitArray(ArrayContext ctx) { for (JsonNode indexInContext : indexesInContext) { // if it's an integral number, just add it as is if (indexInContext.isIntegralNumber() || indexInContext.isLong()) { - indexesToReturn.add(indexInContext.asInt()); + // An index outside int range cannot address a Java array, + // so it is out of bounds and selects nothing (matching + // jsonata.org, e.g. ["a","b"][3000000000] -> undefined). + // Guarding also avoids Jackson 3's asInt() throwing. + if (indexInContext.canConvertToInt()) { + indexesToReturn.add(indexInContext.asInt()); + } } else if (indexInContext.isFloatingPointNumber() || indexInContext.isDouble()) { // If the number is not an integer it is rounded down to an // integer according to JSONATA spec @@ -1323,21 +1346,25 @@ public JsonNode visitComp_op(MappingExpressionParser.Comp_opContext ctx) { "The expressions either side of operator \"<\" must evaluate to numeric or string values"); } else if (left.isBoolean() || right.isBoolean()) { result = null; - } else if (left.isFloatingPointNumber() || right.isFloatingPointNumber()) { + } else if ((left.isFloatingPointNumber() || right.isFloatingPointNumber()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() < right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; - } else if (left.isDouble() || right.isDouble()) { + } else if ((left.isDouble() || right.isDouble()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() < right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isIntegralNumber() && right.isIntegralNumber()) { - result = (left.asLong() < right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) < 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isLong() && right.isLong()) { - result = (left.asLong() < right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) < 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else { if (!lIsComparable || !rIsComparable) { - // signal expression - result = null; + // A non-scalar operand (e.g. an array or object) cannot be + // ordered. The reference implementation (jsonata.org) raises + // "...must evaluate to numeric or string values" here rather + // than returning an empty result (e.g. [1,2] < 4.1). + throw new EvaluateRuntimeException( + "The expressions either side of operator \"<\" must evaluate to numeric or string values"); } else if (left.getNodeType() != right.getNodeType()) { throw new EvaluateRuntimeException("The values " + left.toString() + " and " + right.toString() - + " either side of operator \">\" must be of the same data type"); + + " either side of operator \"<\" must be of the same data type"); } else { result = (left.asText().compareTo(right.asText()) < 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } @@ -1350,18 +1377,22 @@ public JsonNode visitComp_op(MappingExpressionParser.Comp_opContext ctx) { "The expressions either side of operator \">\" must evaluate to numeric or string values"); } else if (left.isBoolean() || right.isBoolean()) { result = null; - } else if (left.isFloatingPointNumber() || right.isFloatingPointNumber()) { + } else if ((left.isFloatingPointNumber() || right.isFloatingPointNumber()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() > right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; - } else if (left.isDouble() || right.isDouble()) { + } else if ((left.isDouble() || right.isDouble()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() > right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isIntegralNumber() && right.isIntegralNumber()) { - result = (left.asLong() > right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) > 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isLong() && right.isLong()) { - result = (left.asLong() > right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) > 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else { if (!lIsComparable || !rIsComparable) { - // signal expression - return null; + // A non-scalar operand (e.g. an array or object) cannot be + // ordered. The reference implementation (jsonata.org) raises + // "...must evaluate to numeric or string values" here rather + // than returning an empty result (e.g. [1,2] > 4.1). + throw new EvaluateRuntimeException( + "The expressions either side of operator \">\" must evaluate to numeric or string values"); } if (left.getNodeType() != right.getNodeType()) { throw new EvaluateRuntimeException("The values " + left.toString() + " and " + right.toString() @@ -1377,18 +1408,22 @@ public JsonNode visitComp_op(MappingExpressionParser.Comp_opContext ctx) { "The expressions either side of operator \"<=\" must evaluate to numeric or string values"); } else if (left.isBoolean() || right.isBoolean()) { result = null; - } else if (left.isFloatingPointNumber() || right.isFloatingPointNumber()) { + } else if ((left.isFloatingPointNumber() || right.isFloatingPointNumber()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() <= right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; - } else if (left.isDouble() || right.isDouble()) { + } else if ((left.isDouble() || right.isDouble()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() <= right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isIntegralNumber() && right.isIntegralNumber()) { - result = (left.asLong() <= right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) <= 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isLong() && right.isLong()) { - result = (left.asLong() <= right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) <= 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else { if (!lIsComparable || !rIsComparable) { - // signal expression - result = null; + // A non-scalar operand (e.g. an array or object) cannot be + // ordered. The reference implementation (jsonata.org) raises + // "...must evaluate to numeric or string values" here rather + // than returning an empty result (e.g. [1,2] <= 4.1). + throw new EvaluateRuntimeException( + "The expressions either side of operator \"<=\" must evaluate to numeric or string values"); } else if (left.getNodeType() != right.getNodeType()) { throw new EvaluateRuntimeException("The values " + left.toString() + " and " + right.toString() + " either side of operator \"<=\" must be of the same data type"); @@ -1404,18 +1439,22 @@ public JsonNode visitComp_op(MappingExpressionParser.Comp_opContext ctx) { "The expressions either side of operator \">=\" must evaluate to numeric or string values"); } else if (left.isBoolean() || right.isBoolean()) { result = null; - } else if (left.isFloatingPointNumber() || right.isFloatingPointNumber()) { + } else if ((left.isFloatingPointNumber() || right.isFloatingPointNumber()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() >= right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; - } else if (left.isDouble() || right.isDouble()) { + } else if ((left.isDouble() || right.isDouble()) && left.isNumber() && right.isNumber()) { result = (left.asDouble() >= right.asDouble()) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isIntegralNumber() && right.isIntegralNumber()) { - result = (left.asLong() >= right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) >= 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else if (left.isLong() && right.isLong()) { - result = (left.asLong() >= right.asLong()) ? BooleanNode.TRUE : BooleanNode.FALSE; + result = (left.bigIntegerValue().compareTo(right.bigIntegerValue()) >= 0) ? BooleanNode.TRUE : BooleanNode.FALSE; } else { if (!lIsComparable || !rIsComparable) { - // signal expression - result = null; + // A non-scalar operand (e.g. an array or object) cannot be + // ordered. The reference implementation (jsonata.org) raises + // "...must evaluate to numeric or string values" here rather + // than returning an empty result (e.g. [1,2] >= 4.1). + throw new EvaluateRuntimeException( + "The expressions either side of operator \">=\" must evaluate to numeric or string values"); } else if (left.getNodeType() != right.getNodeType()) { throw new EvaluateRuntimeException("The values " + left.toString() + " and " + right.toString() + " either side of operator \">=\" must be of the same data type"); @@ -2705,16 +2744,22 @@ public JsonNode visitSeq(SeqContext ctx) { result = factory.arrayNode(); if (start != null && end != null) { - int iStart = start.asInt(); - int iEnd = end.asInt(); - int count = iEnd - iStart + 1; - if (iEnd > iStart && count > 10000000) { - // note: below should read 1e7 not 1e6... - throw new EvaluateRuntimeException(ERR_TOO_BIG + count + "."); - } - for (int i = start.asInt(); i <= end.asInt(); i++) { - ((ArrayNode) result).add(new LongNode(i)); // use longs to align with the output of - // visitNumber + // Work in BigInteger so that bounds and the sequence size cannot + // overflow int/long: asInt()/asLong() throw under Jackson 3 for bounds + // outside their range (e.g. [1..1e19]), and the old int count could + // silently overflow. bigIntegerValue() never throws for integral values. + BigInteger biStart = start.bigIntegerValue(); + BigInteger biEnd = end.bigIntegerValue(); + if (biEnd.compareTo(biStart) >= 0) { + BigInteger count = biEnd.subtract(biStart).add(BigInteger.ONE); + if (count.compareTo(BigInteger.valueOf(10000000L)) > 0) { + // note: below should read 1e7 not 1e6... + throw new EvaluateRuntimeException(ERR_TOO_BIG + count + "."); + } + for (long i = biStart.longValue(); i <= biEnd.longValue(); i++) { + ((ArrayNode) result).add(new LongNode(i)); // use longs to align with the output of + // visitNumber + } } } lastVisited = METHOD; @@ -2916,7 +2961,11 @@ public JsonNode visitUnary_op(MappingExpressionParser.Unary_opContext ctx) { } else if (operand.isDouble()) { result = new DoubleNode(-operand.asDouble()); } else if (operand.isIntegralNumber()) { - if (operand.asLong() == Long.MAX_VALUE) { + if (!operand.canConvertToLong()) { + // A data-sourced BigIntegerNode outside long range: negate + // exactly rather than letting asLong() throw under Jackson 3. + result = new BigIntegerNode(operand.bigIntegerValue().negate()); + } else if (operand.asLong() == Long.MAX_VALUE) { result = new LongNode(-operand.asLong() - 1L); } else { result = new LongNode(-operand.asLong()); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java index d21bf119..4c9aa6ba 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FormatBaseFunction.java @@ -88,7 +88,10 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex if (Math.abs((double) l - d) == 0.5 && l % 2 == 1) { l--; } - final int number = (int) l.longValue(); + // use the full long value rather than narrowing to a 32-bit int, + // which overflowed for large ids (e.g. $formatBase(5890840712243076) + // returned "1008002948" instead of the full value, per jsonata.org) + final long number = l.longValue(); // Check to see if we have an radix argument and read it if we do int radix = 10; @@ -115,7 +118,7 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } // Convert the number to a string in the specified base - result = new StringNode(Integer.toString(number, radix)); + result = new StringNode(Long.toString(number, radix)); } else { throw new EvaluateRuntimeException(ERR_ARG1BADTYPE); } diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java index 20288a08..812c53fe 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisFunction.java @@ -28,6 +28,7 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; +import tools.jackson.core.JacksonException; import tools.jackson.databind.JsonNode; import tools.jackson.databind.node.JsonNodeFactory; import tools.jackson.databind.node.StringNode; @@ -87,7 +88,17 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex return null; } if (argNumber.isNumber()) { - final Long millis = argNumber.asLong(); + long millis; + try { + // asLong() truncates in-range fractional millis (e.g. 3.333 -> 3) + // but under Jackson 3 throws when the magnitude exceeds long range. + // Convert that to a controlled JSONata error rather than leaking a + // raw Jackson exception (reference: new Date(1e30) -> Invalid Date). + millis = argNumber.asLong(); + } catch (JacksonException ex) { + throw new EvaluateRuntimeException( + String.format(Constants.ERR_MSG_NUMBER_OUT_OF_RANGE, argNumber.asText())); + } String pictureStr = null; if (picture != null && picture.isNull() == false) { pictureStr = picture.asText(); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java index 3aff442d..d314b98a 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/FromMillisZonedFunction.java @@ -28,6 +28,7 @@ import com.api.jsonata4java.expressions.utils.Constants; import com.api.jsonata4java.expressions.utils.DateTimeUtils; import com.api.jsonata4java.expressions.utils.FunctionUtils; +import tools.jackson.core.JacksonException; import tools.jackson.databind.JsonNode; import tools.jackson.databind.node.JsonNodeFactory; import tools.jackson.databind.node.StringNode; @@ -87,7 +88,17 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex return null; } if (argNumber.isNumber()) { - final Long millis = argNumber.asLong(); + long millis; + try { + // asLong() truncates in-range fractional millis (e.g. 3.333 -> 3) + // but under Jackson 3 throws when the magnitude exceeds long range. + // Convert that to a controlled JSONata error rather than leaking a + // raw Jackson exception (reference: new Date(1e30) -> Invalid Date). + millis = argNumber.asLong(); + } catch (JacksonException ex) { + throw new EvaluateRuntimeException( + String.format(Constants.ERR_MSG_NUMBER_OUT_OF_RANGE, argNumber.asText())); + } String pictureStr = null; if (picture != null && picture.isNull() == false) { pictureStr = picture.asText(); diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java index fe232720..c98076e8 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/JoinFunction.java @@ -116,11 +116,16 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex JsonNode element = elements.next(); if (element.isTextual()) { stringJoiner.add(element.asText()); - } else if (element.isArray()) { - for (Iterator it = ((ArrayNode) element).iterator(); it.hasNext();) { - stringJoiner.add(it.next().textValue()); - } } else { + // Every element must be a string. The reference + // implementation (jsonata.org) raises "Argument 1 of + // function join must be an array of strings" for any + // non-string element, including a nested array + // ($join([[1, 2]]) and $join([["a", "b"]]) both error); + // it does not flatten nested arrays. Match that controlled + // error rather than flattening or emitting garbage. This + // also avoids Jackson 3's textValue()/stringValue() + // throwing a raw JsonNodeException for a non-String node. throw new EvaluateRuntimeException(ERR_MSG_ARG1_ARR_STR); } } // WHILE diff --git a/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java b/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java index 1a6af672..a742630c 100644 --- a/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java +++ b/src/main/java/com/api/jsonata4java/expressions/functions/SumFunction.java @@ -86,6 +86,11 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex // also complain if any non-numeric types are included in the // array throw new EvaluateRuntimeException(ERR_ARG_TYPE); + } else if (!a.canConvertToLong()) { + // an integral element too large for a long (data-sourced + // BigIntegerNode): sum as doubles, matching jsonata.org, and + // avoiding asLong() throwing under Jackson 3 + shouldReturnAsLong = false; } } @@ -104,7 +109,12 @@ public JsonNode invoke(ExpressionsVisitor expressionVisitor, Function_callContex } } else if (argArray.isIntegralNumber()) { - return new LongNode(argArray.asLong()); + if (argArray.canConvertToLong()) { + return new LongNode(argArray.asLong()); + } + // too large for a long (data-sourced BigIntegerNode): return as a + // double, matching jsonata.org, rather than throwing under Jackson 3 + return new DoubleNode(argArray.asDouble()); } else if (argArray.isFloatingPointNumber() || argArray.isDouble()) { return new DoubleNode(argArray.asDouble()); } else { diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java index e73a8efe..49350551 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/BooleanUtils.java @@ -86,7 +86,12 @@ public static boolean convertJsonNodeToBoolean(JsonNode node) { case NULL: return false; case BINARY: - return node.asBoolean(); + // JSON (and the jsonata.org reference) has no binary type, so + // there is no reference semantics to match; Jackson 2 returned + // false here, and Jackson 3's no-arg asBoolean() throws for a + // BinaryNode. Return false, consistent with the POJO/MISSING/ + // default cases below and with the prior behavior. + return false; case ARRAY: { // recurse, returning true as soon as we see an element that casts // to true diff --git a/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java b/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java index 76005f30..29a76bf2 100644 --- a/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java +++ b/src/test/java/com/api/jsonata4java/expressions/BasicExpressionsTests.java @@ -2281,4 +2281,134 @@ public void testComplexSelection() throws Exception { "[{\"a\":[{\"b\":1}]},{\"a\":[{\"b\":2}]}]"); } + /** + * Ordering operators compare numbers to numbers and strings to strings. + * When the two operands have different types (e.g. number vs string) the + * reference implementation (jsonata.org) raises "...must be of the same + * data type" rather than coercing. Regression guard for issue #432: the + * Jackson 3 migration must not let a float operand silently coerce a + * string on the other side, and the reported operator must be the one + * actually used (the "<" branch previously mis-reported ">"). + */ + @Test + public void testOrderingAcrossTypes() throws Exception { + // valid same-type comparisons still evaluate normally + simpleTest("3 < 4.1", "true"); + simpleTest("3.0 < 4.1", "true"); + simpleTest("3.14 < 4.15", "true"); + simpleTest("5.5 < 6", "true"); + simpleTest("5.5 > 6", "false"); + simpleTest("5.5 <= 6", "true"); + simpleTest("5.5 >= 6", "false"); + simpleTest("\"a\" < \"b\"", "true"); + + // number-vs-string is a type mismatch for every ordering operator, and + // the message names the operator that was used + simpleTestExpectException("3.14 < \"abc\"", + "The values 3.14 and \"abc\" either side of operator \"<\" must be of the same data type"); + simpleTestExpectException("5 < \"3\"", + "The values 5 and \"3\" either side of operator \"<\" must be of the same data type"); + simpleTestExpectException("3.14 > \"abc\"", + "The values 3.14 and \"abc\" either side of operator \">\" must be of the same data type"); + simpleTestExpectException("3.14 <= \"abc\"", + "The values 3.14 and \"abc\" either side of operator \"<=\" must be of the same data type"); + simpleTestExpectException("3.14 >= \"abc\"", + "The values 3.14 and \"abc\" either side of operator \">=\" must be of the same data type"); + + // A string that happens to parse as a number must NOT be silently + // coerced when the other operand is a float. This is the exact + // coercion the fix guards against, and it must hold identically for + // all four ordering operators, with the string on either side. + simpleTestExpectException("\"3\" < 4.1", + "The values \"3\" and 4.1 either side of operator \"<\" must be of the same data type"); + simpleTestExpectException("4.1 < \"3\"", + "The values 4.1 and \"3\" either side of operator \"<\" must be of the same data type"); + simpleTestExpectException("\"3\" > 4.1", + "The values \"3\" and 4.1 either side of operator \">\" must be of the same data type"); + simpleTestExpectException("4.1 > \"3\"", + "The values 4.1 and \"3\" either side of operator \">\" must be of the same data type"); + simpleTestExpectException("\"3\" <= 4.1", + "The values \"3\" and 4.1 either side of operator \"<=\" must be of the same data type"); + simpleTestExpectException("4.1 <= \"3\"", + "The values 4.1 and \"3\" either side of operator \"<=\" must be of the same data type"); + simpleTestExpectException("\"3\" >= 4.1", + "The values \"3\" and 4.1 either side of operator \">=\" must be of the same data type"); + simpleTestExpectException("4.1 >= \"3\"", + "The values 4.1 and \"3\" either side of operator \">=\" must be of the same data type"); + } + + /** + * Equality and the "in" operator compare across types by returning + * false/true rather than throwing, and never coerce a string to a number. + * Regression guard for issue #432. + */ + @Test + public void testEqualityAndMembershipAcrossTypes() throws Exception { + simpleTest("2 = \"2\"", "false"); + simpleTest("2 != \"2\"", "true"); + simpleTest("2 in [1,2,3]", "true"); + // the string "2" is not a member of an array of numbers + simpleTest("\"2\" in [1,2,3]", "false"); + } + + /** + * $join requires a flat array of strings. Any non-string element - a + * number, or even a nested array - is an error; the reference + * implementation (jsonata.org) does not flatten nested arrays. Regression + * guard for issue #434. + */ + @Test + public void testJoinRequiresArrayOfStrings() throws Exception { + // valid flat array of strings still joins + simpleTest("$join([\"a\", \"b\"])", "\"ab\""); + simpleTest("$join([\"a\", \"b\", \"c\"])", "\"abc\""); + + final String err = "Argument 1 of function $join must be an array of strings"; + simpleTestExpectException("$join([1, 2])", err); + simpleTestExpectException("$join([[1, 2]])", err); + simpleTestExpectException("$join([[\"a\", \"b\"]])", err); + } + + /** + * Issue #433: out-of-range numeric values must not leak a raw Jackson 3 + * JsonNodeException from asInt()/asLong(). Bounds, array indexes and numeric + * functions now use the widest-safe representation (BigInteger/double) or a + * controlled JSONata error, matching jsonata.org 2.2.1 where known. + */ + @Test + public void testOutOfRangeNumericCoercion() throws Exception { + // Range bounds beyond int/long no longer crash; they raise the controlled + // "sequence too big" error (matching jsonata.org's range-size limit). + simpleTestExpectException("[1..1e19]", + "The size of the sequence allocated by the range operator (..) must not exceed 1e6. Attempted to allocate 10000000000000000000."); + simpleTestExpectException("[1..3000000000]", + "The size of the sequence allocated by the range operator (..) must not exceed 1e6. Attempted to allocate 3000000000."); + // an ordinary small range is unaffected + simpleTest("[1..5]", "[1,2,3,4,5]"); + + // An array index outside int range is out of bounds -> selects nothing + // (undefined), matching jsonata.org, rather than throwing. + test("[\"a\", \"b\"][3000000000]", (String) null, null, null); + + // $formatBase uses the full (long) value instead of a 32-bit narrowed int + // ($formatBase(5890840712243076) previously overflowed to "1008002948"). + simpleTest("$formatBase(5890840712243076)", "\"5890840712243076\""); + simpleTest("$formatBase(255, 16)", "\"ff\""); + + // $fromMillis with millis beyond long range raises a controlled error + // rather than a raw JsonNodeException (reference: Invalid Date). + simpleTestExpectException("$fromMillis(1e30)", "Number out of range: \"1.0E30\""); + + // Data-sourced BigInteger operands (which numeric literals never produce, + // since large literals become doubles) are handled without crashing. + final String bigs = "[99999999999999999999999999, 99999999999999999999999998]"; + // distinct large integers compare exactly via BigInteger + test("$[0] = $[1]", "false", null, bigs); + test("$[0] > $[1]", "true", null, bigs); + test("$[1] < $[0]", "true", null, bigs); + test("$[0] >= $[0]", "true", null, bigs); + // unary minus negates a big integer exactly + test("-$", "-99999999999999999999999999", null, "99999999999999999999999999"); + } + } From da0712c69cae270b390e50dc8197b1f6a27d5fc6 Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 17:04:29 -0400 Subject: [PATCH 7/9] Fix Maven build warnings in pom.xml - Export com.api.jsonata4java.expressions.regex so bnd no longer flags it as a private reference leaked through the public API of the com.api.jsonata4java and com.api.jsonata4java.expressions exports. - Remove empty from maven-compiler-plugin (not a valid parameter for that plugin). - Remove from maven-assembly-plugin single goal (not a valid parameter; exclusions belong in an assembly descriptor). Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- pom.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index a253d188..d08e2230 100644 --- a/pom.xml +++ b/pom.xml @@ -236,7 +236,6 @@ 17 17 - @@ -303,9 +302,6 @@ jar-with-dependencies - - src/test/resources/* - @@ -331,6 +327,7 @@ com.api.jsonata4java.expressions.generated, \ com.api.jsonata4java.expressions.path, \ com.api.jsonata4java.expressions.path.generated, \ + com.api.jsonata4java.expressions.regex, \ com.api.jsonata4java.expressions.utils ]]> Bundle-Developers: wnm3; email=wnm3@us.ibm.com; From 2a62118f58e96883bbc790f450eaa932a8e844c7 Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 17:14:48 -0400 Subject: [PATCH 8/9] Document Maven build-warning cleanup in migration design doc (#430) Record the pom.xml build-warning fixes (bnd private-reference exports, invalid maven-compiler-plugin/maven-assembly-plugin parameters) and note that the gpg.passphrase deprecation originates from local settings.xml, not the project pom. Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- docs/specs/Jackson-3-Migration-Design.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/specs/Jackson-3-Migration-Design.md b/docs/specs/Jackson-3-Migration-Design.md index c0e5baeb..224eb4a5 100644 --- a/docs/specs/Jackson-3-Migration-Design.md +++ b/docs/specs/Jackson-3-Migration-Design.md @@ -125,6 +125,27 @@ becomes unreachable, or the type is no longer resolvable, replace with - **JPMS.** No `module-info.java` exists; no module changes required. - No other plugin configuration references Jackson. +### Maven build-warning cleanup (unrelated to Jackson, done on this branch) + +While migrating, three pre-existing Maven warnings surfaced on every build and were fixed in +`pom.xml`: + +- **bnd private-reference warnings (×2).** The exported `com.api.jsonata4java` and + `com.api.jsonata4java.expressions` packages expose types from + `com.api.jsonata4java.expressions.regex` (`RegexEngine`, `RegexPattern`, …) in their public API, + but that sub-package was not in the `Export-Package` list, so bnd flagged it as a leaked private + reference. Added `com.api.jsonata4java.expressions.regex` to `Export-Package`. +- **`additionalClasspathElements` unknown (×2).** Removed the empty + `` from `maven-compiler-plugin` — not a valid parameter for that + plugin (it did nothing). +- **`excludes` unknown on assembly plugin.** Removed `` from the `maven-assembly-plugin` + `single` goal — not a valid parameter there (exclusions belong in an assembly descriptor); it was + silently ignored and does not affect the produced `jar-with-dependencies`. + +A fourth warning — `gpg.passphrase` deprecated — originates from the developer's +`~/.m2/settings.xml` (an `activeByDefault` profile setting the deprecated property), **not** from +`pom.xml`, and is resolved locally by removing that property and relying on `gpg-agent`. + ## Out of scope - Any behavioral changes beyond what the package/API migration requires. From a563a761fcecc2435f3b2f1c4a34ed068f24e5f1 Mon Sep 17 00:00:00 2001 From: wnm3 Date: Tue, 7 Jul 2026 17:27:52 -0400 Subject: [PATCH 9/9] Ignore local .superpowers/ tooling directory Co-Authored-By: Claude Opus 4.8 Signed-off-by: wnm3 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 61204ad0..bb6582e8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ !/.idea/workspace.xml /JSONata4Java.iml /setupenv.cmd +/.superpowers/