diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..74cf2cfa93 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: CI + +on: + push: + branches: [ master, develop ] + pull_request: + branches: [ master, develop ] + +jobs: + build: + name: Build & Test (Java 25) + runs-on: ubuntu-latest + + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '25' + cache: maven + + # JOGL opens a display connection during class initialisation even in + # headless mode on some paths. xvfb provides a virtual framebuffer so + # those code paths don't abort with "no display" errors on the runner. + - name: Install Xvfb + run: sudo apt-get install -y xvfb + + - name: Compile + run: mvn --batch-mode --no-transfer-progress compile + + - name: Test + # AWT headless is already set via maven-surefire-plugin in pom.xml; + # xvfb-run provides a fallback display for any JOGL-initialising tests. + run: xvfb-run --auto-servernum mvn --batch-mode --no-transfer-progress test + + - name: Upload test reports on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: surefire-reports-java25 + path: target/surefire-reports/ + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..f45094df13 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,52 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' # e.g. v2.3.0 + +jobs: + release: + name: Build & publish release + runs-on: ubuntu-latest + permissions: + contents: write # needed to create GitHub Release and upload assets + + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '25' + cache: maven + + - name: Install Xvfb + run: sudo apt-get install -y xvfb + + # Compile, test, package, and generate Javadoc in one Maven invocation. + # Tests run before packaging — refuse to release a broken build. + - name: Build, test, and package + run: xvfb-run --auto-servernum mvn --batch-mode --no-transfer-progress verify javadoc:javadoc + + # Zip the Javadoc tree so it can be attached as a single release asset. + - name: Zip Javadoc + run: | + VERSION="${GITHUB_REF_NAME#v}" + cd target/site + zip -r "../../worldwind-java-${VERSION}-javadoc.zip" apidocs/ + echo "RELEASE_VERSION=${VERSION}" >> "$GITHUB_ENV" + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: "WorldWind Java ${{ env.RELEASE_VERSION }}" + body: | + See [RELEASE_NOTES.txt](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/RELEASE_NOTES.txt) for details. + files: | + target/worldwind-java-${{ env.RELEASE_VERSION }}.jar + worldwind-java-${{ env.RELEASE_VERSION }}-javadoc.zip + draft: false + prerelease: false diff --git a/.travis.yml b/.travis.yml.archived similarity index 100% rename from .travis.yml rename to .travis.yml.archived diff --git a/LICENSE.jackson.txt b/LICENSE.jackson.txt index 3eaf591bec..fbf5528eff 100644 --- a/LICENSE.jackson.txt +++ b/LICENSE.jackson.txt @@ -1,13 +1,24 @@ -This copy of Jackson JSON processor is licensed under the -Apache (Software) License, version 2.0 ("the License"). -See the License for details about distribution rights, and the -specific rights regarding derivate works. +Jackson Core 2.18.2 +------------------- +Jackson is a high-performance JSON processor for Java. -You may obtain a copy of the License at: +Copyright (C) 2007- Tatu Saloranta (tatu.saloranta@iki.fi) and contributors. -http://www.apache.org/licenses/ +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at -A copy is also included with both the the downloadable source code package -and jar that contains class bytecodes, as file "ASL 2.0". In both cases, -that file should be located next to this file: in source distribution -the location should be "release-notes/asl"; and in jar "META-INF/" + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Project home: https://github.com/FasterXML/jackson-core +Maven artifact: com.fasterxml.jackson.core:jackson-core:2.18.2 + +Note: This project previously bundled Jackson 1.x (org.codehaus.jackson) as +vendored source code. That code has been replaced by a Maven dependency on +Jackson Core 2.x (com.fasterxml.jackson.core) as of 2026-04-30. diff --git a/MIGRATION_JAVA25.md b/MIGRATION_JAVA25.md new file mode 100644 index 0000000000..03d2e08dad --- /dev/null +++ b/MIGRATION_JAVA25.md @@ -0,0 +1,440 @@ +# WorldWindJava — Java 25 Migration & Technical Debt Tracker + +**Project:** NASA WorldWind Java v2.2.1 +**Current:** Java 11 (Ant build), with Maven `pom.xml` created 2026-04-30 +**Target:** Full Java 25 LTS compliance — all items below resolved + +Items are ordered roughly by risk and dependency. Check each box when the change is committed and verified. + +--- + +## Quick-reference priority table + +| ID | Item | Priority score | Status | +|----|------|---------------|--------| +| [§1 B1](#1-build-toolchain) | Migrate build system to Maven | — | ✅ Done | +| [§1 B2](#1-build-toolchain) | Set compiler target to Java 25 | — | ✅ Done | +| [§1 B3](#1-build-toolchain) | CI: Travis → GitHub Actions | 24 | ✅ Done | +| [§2](#2-jogl--gluegen-upgrade--highest-risk-item) | JOGL/GlueGen 2.4→2.6 + `--add-opens` | Blocker | ✅ JARs removed | +| [§3](#3-deprecated-wrapper-constructor-calls-74-occurrences) | Boxed-type `new` constructors (74×) | — | ✅ None in WWJ source | +| [§4](#4-browseropener--remove-comappleeiofilemanager) | `BrowserOpener` — remove Apple private API | — | ✅ Done | +| [§5](#5-gdalutils--remove-sunarchdatamodel-system-property) | `GDALUtils` — remove `sun.arch.data.model` | — | ✅ Done | +| [§6 TD-01](#6-jackson--replace-bundled-1x-source-with-jackson-2x-dependency) | Jackson 1.x → Jackson 2.x | 24 | ✅ Done | +| [§7](#7-apache-batik--upgrade-from-bundled-old-version) | Batik 1.7 → 1.17 (build-time rasterizer) | — | ✅ Done | +| [§8 TD-03](#8-junit--upgrade-from-45-to-junit-5) | JUnit 4.5 → JUnit 5 | 16 | ✅ Done | +| [§9](#9-native-webview-jni-binaries--recompile-for-current-platforms) | WebView JNI — recompile for JDK 25 | — | ⬜ | +| [§10](#10-gdal-native-binaries) | GDAL native binaries — validate / rebuild | — | ⬜ | +| [§11](#11-verify-no-remaining-uses-of-removeddeprecated-apis) | Final `jdeprscan` / `jdeps` pass | — | ⬜ | +| [TD-04](#td-04--resolve-todofixme-incomplete-features) | TODO/FIXME incomplete features | 16 | ⬜ | +| [TD-05](#td-05--audit-and-remove-deprecated-api-methods) | 131 deprecated API methods | 15 | ⬜ | +| [TD-07](#td-07--modernise-concurrency-primitives) | 239 raw `synchronized`/`volatile` | 12 | ⬜ | +| [TD-08](#td-08--decompose-god-classes) | God classes (GeometryBuilder 8.6K lines) | 10 | ⬜ | +| [TD-06](#td-06--resolve-suppresswarnings-suppressions) | 490 @SuppressWarnings suppressions | 10 | ⬜ | +| [TD-09](#2-jogl--gluegen-upgrade--highest-risk-item) | JOGL version update | 10 | ⬜ (see §2) | +| [TD-10](#td-10--expand-test-coverage) | Test coverage (~3% baseline) | 9 | ⬜ ongoing | +| [TD-11](#td-11--build-modernisation) | Build modernisation (Ant→Maven) | 8 | ✅ Done | + +> **Priority score** = (Impact + Risk) × (6 − Effort), scale 1–25. Higher = fix sooner. Items without a score are Java 25 migration requirements rather than scored debt items. + +--- + +## 1. Build toolchain + +- [x] **Migrate build system from Ant to Maven** + `pom.xml` created 2026-04-30. Uses `maven-compiler-plugin` 3.13.0, `maven-surefire-plugin` 3.5.2, + `exec-maven-plugin` 3.4.1, and `build-helper-maven-plugin` 3.6.0. + Ant `build.xml` and `nbproject/` are retained for reference but superseded by Maven. + ⚠️ Pending: verify `mvn compile` succeeds end-to-end (requires Java 25 JDK installed locally). + +- [x] **Set compiler source/target to Java 25** + `25` set in `pom.xml` properties. + +- [x] **Update CI from Travis CI + openjdk11 to GitHub Actions with Java 25** (done 2026-04-30) + Created `.github/workflows/ci.yml` — triggers on push/PR to `master`/`develop`; runs + `mvn compile` then `xvfb-run mvn test` on `ubuntu-latest` with Temurin 25; uploads Surefire + reports as an artifact on failure. + Created `.github/workflows/release.yml` — triggers on `v*.*.*` tags; runs full test suite, + packages the JAR, generates Javadoc, then publishes both as GitHub Release assets via + `softprops/action-gh-release`. + `.travis.yml` renamed to `.travis.yml.archived` (history preserved, no longer active). + +--- + +## 2. JOGL / GlueGen upgrade — HIGHEST RISK ITEM + +**~~Current version:~~** ~~`2.4.0-rc-20200306` (a pre-release built with JDK 11 in March 2020)~~ +**Upgraded to:** `2.6.0` declared in `pom.xml` (2026-04-30) + +JOGL 2.4 was built against Java 11. JDK module encapsulation changes in Java 17–25 break +native binding initialisation without explicit `--add-opens` flags. + +### What changes + +- [x] **Replace all bundled JOGL/GlueGen JARs with Maven Central 2.6.0 artifacts** + `pom.xml` now declares `org.jogamp.jogl:jogl-all:2.6.0` and + `org.jogamp.gluegen:gluegen-rt:2.6.0`, each with a `natives-macosx-universal` classifier + dependency. + ⚠️ The old bundled JARs (`jogl-all.jar`, `gluegen-rt.jar`, and all six native JARs) should be + **deleted from the project root** once `mvn compile` is confirmed green. Keeping them now + avoids breaking Ant users before the Maven build is validated. + To add Linux/Windows natives, duplicate the natives dependencies in `pom.xml` using classifiers + `natives-linux-amd64` and `natives-windows-amd64`. + +- [x] **Add required `--add-opens` JVM flags for JOGL on Java 25** + Flags declared in `pom.xml` in three places: + — `` property (single source of truth) + — `maven-surefire-plugin` `` (test execution) + — `exec-maven-plugin` `` (application launch via `mvn exec:exec`) + `run-demo.bash` and `run-demo.bat` updated to delegate to `mvn exec:exec`. + +- [x] **Remove legacy bundled JOGL/GlueGen JARs from project root** (done 2026-04-30) + Removed: `jogl-all.jar`, `jogl-all-natives-*.jar` (3), `gluegen-rt.jar`, + `gluegen-rt-natives-*.jar` (3), `jogl.README.txt`. Retained: `jogl.LICENSE.txt`, + `gluegen.LICENSE.txt` for compliance documentation. + +- [ ] **Verify no breaking API changes between JOGL 2.4.0-rc and 2.6.0** + JOGL stays on 2.x so the public API is intended to be stable, but the rc→release transition + may have changed some internal or deprecated APIs. + _Action:_ Run `mvn compile` with Java 25 installed and triage each compiler error against the + 2.6.0 changelog at https://github.com/sgothel/jogl + +- [ ] **Update `lib-external/jogl-gluegen/` build scripts** + The scripts in this directory build JOGL from source. Update them to target the v2.6.0 tag if + you ever need to rebuild from source. + +--- + +## 3. Deprecated wrapper constructor calls (74 occurrences) + +`new Integer(x)`, `new Long(x)`, `new Double(x)`, `new Float(x)`, `new Boolean(x)`, +`new Short(x)`, `new Byte(x)`, `new Character(x)` — removed in Java 16. + +- [x] **Replace all boxed-type `new` constructors with static factory methods** — N/A + Audit (2026-04-30): zero occurrences in WorldWind source. The "74 occurrences" referenced in + the migration doc were inside the vendored `src/org/codehaus/jackson/` source tree, which is + tracked separately under §6 (Jackson replacement). + +--- + +## 4. `BrowserOpener` — remove `com.apple.eio.FileManager` + +File: `src/gov/nasa/worldwind/util/BrowserOpener.java` + +- [x] **Replace `browseMacOS()` with `java.awt.Desktop.browse(URI)`** (done 2026-04-30) + Removed `com.apple.eio.FileManager` reflection, `browseWindows`, and `browseUnix`. The entire + class now delegates to `Desktop.getDesktop().browse(url.toURI())` — one method, cross-platform. + +- [x] **Replace `Runtime.getRuntime().exec(String)` calls in the same file** (done 2026-04-30) + Resolved by the Desktop.browse() rewrite above; all `Runtime.exec` calls eliminated. + +--- + +## 5. `GDALUtils` — remove `sun.arch.data.model` system property + +File: `src/gov/nasa/worldwind/util/gdal/GDALUtils.java` (line ~155) + +- [x] **Replace `System.getProperty("sun.arch.data.model")` with `System.getProperty("os.arch")`** (done 2026-04-30) + `is32bitArchitecture()` now uses `os.arch` exclusively, matching on `x86`, `i386`, `i686`. + The old `sun.arch.data.model` primary lookup and its GNU Java fallback comment are removed. + +--- + +## 6. Jackson — replace bundled 1.x source with Jackson 2.x dependency + +The entire Jackson 1.x library (circa 2009) is committed as Java source in +`src/org/codehaus/jackson/`. This is extremely stale and carries security risk. (See also +[TD-01](#td-01--replace-embedded-jackson-1x) in the tech debt register — score: 24.) + +- [x] **Remove `src/org/codehaus/jackson/` source tree entirely** (done 2026-04-30) + 75 vendored source files deleted. `src/org/` directory removed (was empty after deletion). + +- [x] **Add Jackson 2.x as a Maven dependency** (done 2026-04-30) + Only `jackson-core` is needed — WorldWind uses the streaming API only, not ObjectMapper. + ```xml + + com.fasterxml.jackson.core + jackson-core + 2.18.2 + + ``` + +- [x] **Update all call sites** (done 2026-04-30) + 5 files migrated: `BasicJSONEvent`, `BasicJSONEventParserContext`, `JSONDoc`, + `GeoJSONDoc`, `GeoJSONEventParserContext`. + Changes: `org.codehaus.jackson.*` → `com.fasterxml.jackson.core.*`; + `factory.createJsonParser()` → `factory.createParser()`; + `parser.getCurrentName()` → `parser.currentName()` (deprecated in Jackson 2.12+). + `mvn compile` passes with zero Jackson-related warnings. + +- [x] **Update `LICENSE.jackson.txt`** (done 2026-04-30) + Updated to reference FasterXML Jackson Core 2.18.2 (Apache 2.0). + +--- + +## 7. Apache Batik — upgrade from bundled old version + +> **Correction (2026-04-30):** Batik is **not** a compile or runtime dependency — zero +> `import org.apache.batik.*` statements exist in WorldWind source. It is used exclusively +> as a **CLI SVG rasterizer** in `release-build.xml` to convert 21,520 MIL-STD-2525 SVG +> symbol files into PNGs at release time. `batik-transcoder` and `batik-svggen` are not needed. + +`lib-external/batik/` contained **Batik 1.7+r608262** (built ca. 2008 with Ant 1.6.5, 7.7 MB). +Batik 1.7 is incompatible with Java 9+ module encapsulation when run as a forked CLI process. + +- [x] **Replace `lib-external/batik/` with a Maven profile using Batik 1.17** (done 2026-04-30) + Added profile `rasterize-milstd2525` to `pom.xml`. Uses `maven-antrun-plugin` with + `batik-all:1.17` + `xml-apis-ext:1.3.04` as plugin dependencies; runs + `org.apache.batik.apps.rasterizer.Main` in a forked JVM with the full Batik classpath + via `maven.plugin.classpath`. Handles both the main 128×128 pass and the FEBA 16 px override. + + **Usage:** + ```bash + mvn -Prasterize-milstd2525 generate-resources # SVG → PNG only + mvn -Prasterize-milstd2525 package # + zip into milstd2525-symbols.zip + ``` + + `lib-external/batik/` (7.7 MB) removed. Normal `mvn compile` / `mvn test` are unaffected. + +--- + +## 8. JUnit — upgrade from 4.5 to JUnit 5 + +The bundled `junit-4.5.jar` is from 2008 and has no JDK 25 validation. (See also +[TD-03](#td-03--upgrade-junit-45--junit-5) in the tech debt register — score: 16.) + +**✅ Completed 2026-04-30.** + +- [x] **Replace `junit:junit:4.13.2` with JUnit 5 (Jupiter) via Maven** (done) + ```xml + + org.junit.jupiter + junit-jupiter + 5.11.4 + test + + ``` + `junit-jupiter` is the aggregator artifact — it pulls in `junit-jupiter-api`, + `junit-jupiter-engine` (for Surefire), and `junit-jupiter-params` (for + `@ParameterizedTest`). `maven-surefire-plugin` 3.5.2 auto-discovers Jupiter tests. + +- [x] **Migrate all 49 test files from JUnit 4 to JUnit 5** (done) + - `@RunWith(JUnit4.class)` removed (47 files) + - `@RunWith(Parameterized.class)` → `@ParameterizedTest @MethodSource` (2 files: + `KMLExportTest`, `ShapeAttributesTest`; constructors removed, data method returns + `Stream>` / `Stream`) + - `import org.junit.*` / specific imports → `org.junit.jupiter.api.*` + - `import static org.junit.Assert.*` → `import static org.junit.jupiter.api.Assertions.*` + - `@Before`/`@After` → `@BeforeEach`/`@AfterEach` (8 files) + - `@Ignore` → `@Disabled` (4 files) + - `@Test(expected = UnsupportedOperationException.class)` → `assertThrows(...)` (1 occurrence) + - **1,688 assert argument-order fixes** across 35 files (JUnit 4 puts message first; + JUnit 5 puts message last) + - Private `assertEquals(Iterable,…)` helpers renamed `assertIterablesEqual` in + 3 layer test files to prevent method-name shadowing + - `mvn test-compile` passes with zero errors after migration + +--- + +## 9. Native WebView JNI binaries — recompile for current platforms + +`lib-external/webview/` contains Objective-C (macOS) and C++ (Windows) JNI source code compiled +against old JDK headers. + +- [ ] **Recompile macOS WebView native library** against JDK 25 headers on a macOS build machine + Source: `lib-external/webview/macosx/` — uses `WebKit.framework` (legacy `WebView`, not + `WKWebView`). Note that `WebView` was deprecated by Apple and may need migrating to `WKWebView`. + _Build script:_ `lib-external/webview/macosx/build.sh` + +- [ ] **Recompile Windows WebView native library** against JDK 25 headers + Source: `lib-external/webview/windows/` — uses IE's `IHTMLDocument2` / MSHTML COM interface, + which is legacy on Windows 11. + _Build file:_ `lib-external/webview/windows/WebView.vcxproj` + +- [ ] **Consider whether WebView is still needed** + Both the macOS and Windows native backends rely on deprecated/legacy browser engines (Apple + WebView, MSHTML). If the embedded browser feature is not actively used, removing it would + eliminate a significant maintenance burden. + +--- + +## 10. GDAL native binaries + +The native GDAL binaries in `lib-external/gdal/` are old builds. They may work fine at runtime +(JNI ABI is stable), but should be validated. + +- [ ] **Verify `gdal.jar` + native GDAL binaries load correctly under Java 25** + Run the GDAL integration tests (`test/gov/nasa/worldwind/data/`) on each target platform. If + the binaries fail to load, rebuild GDAL from source against JDK 25 headers. + +--- + +## 11. Verify no remaining uses of removed/deprecated APIs + +After all of the above changes, do a final pass with the Java migration analysis tooling. + +- [ ] **Run `jdeprscan --release 25`** against the compiled classes to catch any remaining + deprecated API usage + ```bash + jdeprscan --release 25 --class-path build/classes + ``` + +- [ ] **Run `jdeps --jdk-internals`** to identify any remaining JDK internal API references + ```bash + jdeps --jdk-internals -cp build/WorldWindJava.jar + ``` + +- [ ] **Ensure all tests pass on Java 25**: `mvn test` + +--- + +## Technical Debt Register + +Items below are pure tech debt — not Java 25 requirements — but should be addressed alongside +the migration to avoid compounding the maintenance burden. Scored on +**Priority = (Impact + Risk) × (6 − Effort)**; Impact/Risk/Effort each 1–5. + +### TD-01 · Replace embedded Jackson 1.x *(score: 24)* + +See full treatment in [§6](#6-jackson--replace-bundled-1x-source-with-jackson-2x-dependency). + +--- + +### TD-02 · CI: Travis → GitHub Actions *(score: 24)* + +See full treatment in [§1](#1-build-toolchain) (CI item). + +--- + +### TD-03 · Upgrade JUnit 4.5 → JUnit 5 *(score: 16)* + +**✅ Done 2026-04-30.** See full treatment in [§8](#8-junit--upgrade-from-45-to-junit-5). + +--- + +### TD-04 · Resolve TODO/FIXME incomplete features *(score: 16)* + +- **Status:** ⬜ Open +- **Scale:** ~30 TODO/FIXME comments across core modules +- **Key instances:** + - `src/.../formats/nmea/NMEAReader.java` — checksum validation not implemented (data + correctness bug, not cosmetic debt) + - `src/.../render/StereoOptionSceneController.java` — "needs to be updated to implement correct + stereo" + - `src/.../wms/WMSTiledImageLayer.java` — "consolidate common code in URLBuilder" + - `src/.../render/DrawContext*.java` — commented-out OrderedRenderable logging with TODO markers +- **Action:** + 1. `grep -rn "TODO\|FIXME\|HACK\|XXX" src/` for full inventory. + 2. File a GitHub Issue for each distinct item. + 3. Fix NMEA checksum first — it is a correctness bug. +- **Effort:** Triage ~0.5 day; NMEA fix ~1 day; stereo rendering ~2–3 days + +--- + +### TD-05 · Audit and remove deprecated API methods *(score: 15)* + +- **Status:** ⬜ Open +- **Scale:** 131 `@Deprecated` annotations +- **Action:** + 1. `grep -rn "@Deprecated" src/` to enumerate. + 2. Classify: (a) remove now — no known external callers; (b) schedule removal + replace + internal callers; (c) retain for public API stability. + 3. Remove category (a) in a single clean-up PR. +- **Effort:** 2–3 days + +--- + +### TD-06 · Resolve @SuppressWarnings suppressions *(score: 10)* + +- **Status:** ⬜ Open +- **Scale:** 490 `@SuppressWarnings` annotations — masking raw-type and unchecked-cast warnings +- **Action:** Remove suppressions file-by-file; fix the resulting warnings. Target ~20/sprint as + background work. +- **Effort:** Ongoing background cadence + +--- + +### TD-07 · Modernise concurrency primitives *(score: 12)* + +- **Status:** ⬜ Open +- **Scale:** 239 raw `synchronized`/`volatile` keywords; no apparent use of `ConcurrentHashMap`, + `AtomicReference`, or `CompletableFuture` +- **Note:** `CONTRIBUTING.md` already mandates `java.util.concurrent` — existing code predates + the rule. +- **Action:** + 1. Profile with VisualVM or async-profiler to find actual contention hotspots. + 2. Replace `synchronized` maps → `ConcurrentHashMap`; counters → `AtomicLong`. + 3. Do not blindly refactor rendering-thread code; validate under multi-window load. +- **Effort:** 1–2 weeks; profile first + +--- + +### TD-08 · Decompose God classes *(score: 10)* + +- **Status:** ⬜ Open +- **Candidates:** + - `src/.../util/GeometryBuilder.java` — ~8,600 lines; logical sections: sphere, cylinder, + polygon, extrusion, normal generation + - `src/.../formats/shapefile/EntityMap.java` — ~4,400 lines + - `src/.../util/WWXML.java` — ~3,900 lines + - `src/.../util/WWIO.java` — ~2,500 lines +- **Action:** Start with `GeometryBuilder` — extract `SphereGeometry`, `CylinderGeometry`, + `PolygonGeometry` as package-private classes, delegated to from `GeometryBuilder`. No behaviour + change; requires full test run to confirm. +- **Effort:** 3–5 days per class + +--- + +### TD-09 · JOGL version update *(score: 10)* + +See full treatment in [§2](#2-jogl--gluegen-upgrade--highest-risk-item). + +--- + +### TD-10 · Expand test coverage *(score: 9)* + +- **Status:** ⬜ Open (ongoing) +- **Baseline:** 49 unit tests across 1,726 source files (~3% file ratio) +- **Strategy:** Target regression safety over a coverage number. Recommended sequence: + 1. `geom/` package — pure math, no rendering dependencies, easiest to test + 2. `formats/nmea/`, `formats/shapefile/` — data-in/data-out, deterministic + 3. `wms/` URL building — string manipulation + 4. Rendering integration tests last — requires `xvfb`, harder to assert correctness +- **Gate:** Soft requirement of at least one new test per non-trivial PR to `develop`. +- **Effort:** Ongoing; 2–3 tests/week compounds quickly + +--- + +### TD-11 · Build modernisation (Ant → Maven) *(score: 8)* + +- **Status:** ✅ Done — `pom.xml` created 2026-04-30. See [§1](#1-build-toolchain). + +--- + +## Summary of removed/breaking changes by Java version + +| Java version | Change | Impact here | +|---|---|---| +| Java 16 | Wrapper type constructors (`new Integer()` etc.) removed | 74 call sites | +| Java 17 | Strong encapsulation enforced — `--illegal-access` no-op | JOGL requires `--add-opens` | +| Java 17 | `SecurityManager` deprecated for removal | Audit needed | +| Java 18 | `Runtime.exec(String)` deprecated | `BrowserOpener` (3 calls) | +| Java 18 | Finalization deprecated for removal | No active `finalize()` overrides found — safe | +| Java 21 | `Thread.stop()` / `Thread.suspend()` removed | Audit: `grep -rn "\.stop()\|\.suspend()"` | +| Java 25 | (LTS target) | All of the above must be resolved | + +--- + +## Audit history + +| Date | Author | Notes | +|------|--------|-------| +| 2026-04-30 | warren | Initial tech debt audit. 1,726 source files, ~532K LOC. 17 debt items identified and scored. | +| 2026-04-30 | warren | Maven `pom.xml` created; JOGL upgraded to 2.6.0 in Maven; `--add-opens` flags added; `run-demo` scripts updated. Fixed invalid XML comment (`--release`, `--add-opens` inside ``). | +| 2026-04-30 | warren | Low-risk fixes: `BrowserOpener` rewritten to `Desktop.browse()`; `GDALUtils.is32bitArchitecture()` migrated to `os.arch`; 9 legacy JOGL/GlueGen JARs removed. `mvn compile` passes clean (1,726 files). | +| 2026-04-30 | warren | CI migration: `.github/workflows/ci.yml` and `release.yml` created; `.travis.yml` archived. | +| 2026-04-30 | warren | Jackson: 75 vendored 1.x source files removed; `jackson-core 2.18.2` added to pom.xml; 5 call-site files migrated to `com.fasterxml.jackson.core.*`. `mvn compile` clean. | +| 2026-04-30 | warren | Batik: corrected understanding (build-time rasterizer only, not a compile dep); `lib-external/batik/` (7.7 MB, Batik 1.7 ca. 2008) removed; `rasterize-milstd2525` Maven profile added using `batik-all:1.17`. | + +--- + +_Last updated: 2026-04-30_ diff --git a/gluegen-rt-natives-linux-amd64.jar b/gluegen-rt-natives-linux-amd64.jar deleted file mode 100644 index 625b8479ed..0000000000 Binary files a/gluegen-rt-natives-linux-amd64.jar and /dev/null differ diff --git a/gluegen-rt-natives-macosx-universal.jar b/gluegen-rt-natives-macosx-universal.jar deleted file mode 100644 index 0e791ff2ce..0000000000 Binary files a/gluegen-rt-natives-macosx-universal.jar and /dev/null differ diff --git a/gluegen-rt-natives-windows-amd64.jar b/gluegen-rt-natives-windows-amd64.jar deleted file mode 100644 index 2ae552be1e..0000000000 Binary files a/gluegen-rt-natives-windows-amd64.jar and /dev/null differ diff --git a/gluegen-rt.jar b/gluegen-rt.jar deleted file mode 100644 index 51cd1a8826..0000000000 Binary files a/gluegen-rt.jar and /dev/null differ diff --git a/jogl-all-natives-linux-amd64.jar b/jogl-all-natives-linux-amd64.jar deleted file mode 100644 index fa74de8f96..0000000000 Binary files a/jogl-all-natives-linux-amd64.jar and /dev/null differ diff --git a/jogl-all-natives-macosx-universal.jar b/jogl-all-natives-macosx-universal.jar deleted file mode 100644 index 23d78f5370..0000000000 Binary files a/jogl-all-natives-macosx-universal.jar and /dev/null differ diff --git a/jogl-all-natives-windows-amd64.jar b/jogl-all-natives-windows-amd64.jar deleted file mode 100644 index 7b8dcff736..0000000000 Binary files a/jogl-all-natives-windows-amd64.jar and /dev/null differ diff --git a/jogl-all.jar b/jogl-all.jar deleted file mode 100644 index ab93476acc..0000000000 Binary files a/jogl-all.jar and /dev/null differ diff --git a/jogl.README.txt b/jogl.README.txt deleted file mode 100644 index 3e024a4ca9..0000000000 --- a/jogl.README.txt +++ /dev/null @@ -1,69 +0,0 @@ - -Java (TM) Binding for the OpenGL (r) API, version 2.4 ------------------------------------------------------------------------------ - -This software is licensed as specified in the LICENSE.txt file. -You must use this software in accordance with the terms -under which the code is licensed. - -This is build version 2.4.0-rc-20200306, based on: - branch origin/master - commit 0779f229b0e9538c640b18b9a4e095af1f5a35b3 - -Instructions for unzipping Java Binding for the OpenGL API, version 2.4 ----------------------------------------------------------------------------------- - -After downloading and unzipping the zip file containing the -JOGL release for your target platform, you will see the -following files in the top directory: - - LICENSE.txt - Userguide.html - README.txt README file (you are reading it now) - -and the following subdirectory: - - etc contains JOGL shell scripts - jar contains JOGL implementation, JAR files - lib contains JOGL implementation, native libraries - jnlp-files contains JOGL jnlp-file templates - -additionally the following Java source zip archives are added, -allowing convenient IDE integration (javadoc, class/method help, etc). -Generated Java source code is included as well. - - nativewindow-java-src.zip contains NativeWindow Java sources, reflecting nativewindow.all.jar - jogl-java-src.zip contains JOGL Java sources, reflecting jogl.all.jar - newt-java-src.zip contains NEWT Java sources, reflecting newt.all.jar - -For instructions on how to use these implementation files -to build or run a JOGL program look at: - http://jogamp.org/ - http://jogamp.org/jogl/ - http://jogamp.org/wiki/index.php/Jogl_Tutorial - http://jogamp.org/wiki/index.php/Jogl_FAQ - -You can verify the version of the build via the JOGL self test: - etc/test.sh (Linux, FreeBSD, MacOSX, ..) - etc\test.bat (Windows) - -You may also have a look at the (outdated) enclosed JOGL user guide, Userguide.html - -Project source code and getting assistance ------------------------------------------- - -JOGL source code can be found at: - - http://jogamp.org/git/ - http://github.com/sgothel/jogl - http://github.com/sgothel/gluegen - - -You can address the JogAmp Community via: ------------------------------------------- - Web http://jogamp.org/ - Forum/Mailinglist http://jogamp.762907.n3.nabble.com/ - JogAmp Channel server: conference.jabber.org room: jogamp - Repository http://jogamp.org/git/ - Email mediastream _at_ jogamp _dot_ org - diff --git a/lib-external/batik/CHANGES b/lib-external/batik/CHANGES deleted file mode 100644 index a36e17996f..0000000000 --- a/lib-external/batik/CHANGES +++ /dev/null @@ -1,1528 +0,0 @@ -Change Log -========== - -The following log records some of the most important changes. -Bug fixing is an on-going task, so it is implied in all sub-releases. - -1.7beta1 -> 1.7 ---------------- - -1. Bugzilla problem reports fixed: - - 26815, 28344, 35165, 36570, 37496, 38498, 40163, 40727, 41205, - 41820, 41947, 41955, 41988, 42014, 42021, 42032, 42075, 42118, - 42137, 42168, 42169, 42196, 42209, 42210, 42212, 42221, 42228, - 42255, 42258, 42311, 42312, 42333, 42381, 42386, 42479, 42504, - 42505, 42543, 42645, 42651, 42697, 42698, 42807, 42961, 42963, - 442968, 3022, 43043, 43045, 43165, 43194, 43195, 43370, 43418, - 443446, 3638, 43657, 43744, 43760, 43764, 43787, 43854, 43871, - 443904, 3953, 44029, 44054, 44092, 44146 - -2. New features - - * xml:id support (http://www.w3.org/TR/xml-id/). - * ElementTraversal support (http://www.w3.org/TR/ElementTraversal/). - * Enhanced DOM Viewer window, contributed from Ivan Andjelkovic, - a Google Summer of Code student. - -3. Improvements - - * Support for cursor="move" on OS X, and cursor="help" on all - platforms. - * Improved conversion to/from WMF. - * data: URIs now supported as external stylesheets, scripts, filters. - * SVG 1.1 feature strings now reported. - * The viewBox="" attribute on is now animatable. - * Implemented SVGSVGelement.getViewBox(). - * A document's document element can now be replaced. - * Performing animation hyperlinking backwards is now supported, as - well as using elements to hyperlink to animations. - * Updated pdf-transcoder.jar to one built from FOP 0.94. - * Squiggle's View Source window is now syntax highlighted. - -4. Bug fixes - - * XPath interface objects now exposed to ECMAScript. - * The three other MIME types for ECMAScript are now really supported - (text/javascript, application/javascript, application/ecmascript). - * Pseudo-elements now parsed properly in CSS selectors. - * Avoid null pointer exception when event-base timing specifiers - in animations reference an element by ID within a shadow tree. - * Invalid min="" and max="" values on animation elements now ignored. - * Corrected CSS cascade order for rules of equal specificity. - * Fixed CSS :lang() processing so that it matches case insenstiviely, - using xml:lang="" as well as lang="", and using proper hyphen- - separated tokens. - * Gradients with gradientUnits="objectBoundingBox" disabled when the - bounding box has zero width or height. - * Avoid an array index exception for certain degenerate motion path - animations. - * Fixed mouse event button reporting. - * Avoid null pointer exception when cloning and - elements. - * Make empty elements result in no rendering for the - filtered element. - * SVGStylable.getPresentationAttribute() now returns null if the given - presentation attribute is not specified on the element. - * Specifying textLength="" on text elements that have non-text nodes - as their first children now works. - * Avoid numerical accuracy issues when sampling frozen animations. - * Event listeners are now removed when elements are removed - from the document. - * Invalid SVG 1.0 feature string removed. - * Ensure animation elements are properly deinitialised when they are - removed from the document. - * Allowed animations in element shadow trees to have syncbase - timing specifiers that refer to elements outside the shadow tree. - * Fixed bug in DOM event removal/dispatch. - * Ensure the animation engine is resumed if it is sleeping when a - beginElement() call is made. - * Avoid a null pointer exception in JSVGScrollPane if the document - doesn't return a bounds. - * Avoid a null pointer exception when painting a GraphicsNode on to an - SVGGraphics2D. - * Rasterizer -cssUser command line argument now resolved against - current working directory. - * Fixed bug in key event dispatching code. - * Decrease memory required for storing animation elements' previous - intervals (used for hyperlinking). - * Avoid infinite loop for animations with multiple, identical begin - (or end) instance times. - * Ensure TIFF and JPEG codecs really aren't compiled unless the relevant - Sun classes are present. - * Avoid null pointer exception when accessing animated marker orient - values. - * Patched Rhino so that the ECMAScript debugger runs on OS X. - * Ensure the animation engine is initialised before the SVGLoad event - is dispatched. - * Restored exception throwing from bridge classes when required - length attributes are missing. - * Duplicated codec classes removed from awt-util jar. - * Avoid null pointer exceptions in DOMMouseEvent objects. - * Motion animation transforms are now applied after the transform="" - attribute. - * Fixed bug in DOM event default action invocation in SVG 1.2 documents. - * Fixed bug in CSS class name matching, which occured only when an - element was declared to be a member of multiple classes, where one - is a prefix of another. - * Fixed bug on OS X where the zoom interactor overlay was not shown. - -5. Misc - - * Official maven artifacts are now supplied. - -1.6 -> 1.7beta1 ---------------- - -1. Bugzilla problem reports fixed: - - 22260, 25428, 28337, 29417, 29552, 32415, 34217, 34234, 34364, - 34847, 34938, 35349, 35480, 35549, 35655, 35661, 35683, 35722, - 35727, 35773, 35878, 35976, 35977, 36165, 36253, 36278, 36309, - 36455, 36483, 36485, 36493, 36511, 36613, 36614, 36615, 36743, - 36745, 36746, 36747, 36769, 36889, 36924, 36933, 37276, 37497, - 37890, 37891, 37892, 37986, 37989, 38045, 38158, 38176, 38178, - 38183, 38379, 38475, 38497, 38549, 38558, 38568, 38750, 38775, - 38782, 38785, 38831, 38872, 38930, 38932, 38933, 38990, 39032, - 39058, 39202, 39297, 39303, 39318, 39361, 39751, 39755, 39784, - 39831, 39838, 40098, 40167, 40336, 40368, 40392, 40393, 40397, - 40403, 40405, 40594, 40605, 40631, 40681, 40686, 40857, 40898, - 40927, 40994, 41079, 41165, 41216, 41234, 41288, 41329, 41331, - 41336, 41473, 43954 - -2. New features - - * DOM Level 3 Core/Events/XPath support. - * Improved WMF transcoder support. - * Override style declaration support. - * Near complete SMIL Animation support. - * SVG 1.2 features: - * resource documents - * shapechange and RenderedBBoxChange events - * SVGGlobal startMouseCapture/stopMouseCapture methods - * handler elements - -3. Improvements - - * The SVG namespace declaration is now not assumed for the document element - when an SVG declaration is not present. Certain non-conformant content - will now be identified as being in error. - * New MacRenderer implementation that avoids 10x slowdown on - Tiger. - * Mutations to flowText contents now cause the rendering to update, and - flowRegion objects are now rendered. - * Support for normalized path segments on SVGAnimatedPathData, thanks to - Andres Toussaint. - * Updated pdf-transcoder.jar to one built from FOP 0.9alpha1: - * This fixes text being drawn as text in PDF. - * JPEG streams being embedded as JPEG. - * Default bitmap dpi is 300. - * Most gradients and patterns are now correct (pattern overflow isn't - handled properly although most of the code is present), and - gradients with complex repeats are rasterized due to difficulties - expressing them in PDF. - * Transcoders with the KEY_EXECUTE_ONLOAD hint set force the document - to be dynamic. - * Added JIIO codecs to Batik (not enabled by default) - * Support for finding XML Parser through JAXP. - * Enhancements to ArabicTextHandler. - * Update Manager's MIN_REPAINT time is now adjustable. - * GraphicsUtil warning about Graphics from BufferedImage - w/o BUFFERED_IMAGE hint is now controllable with property. - * JSVGScrollPane now has 'scrollbarAlwaysVisible' mode. - * Improved Path parser so it is more conformant. - * Updated Rhino to 1.6R5. - * Documents in Squiggle's Go menu now have the full URI as a tooltip. - * Better version number reporting from org.apache.batik.Version. - * Implemented SVGPathElement.getPathSegAtLength. - * Implemented 'getFunctionName' for built in CSS functions. - * Exposed SAXDocumentFactory's parser to subclasses. - * Added a -snapshotTime option to the rasteriser. - * Now using Apache XML Commons External, for SAC, DOM 3 Core, SMIL Animation - and SVG 1.1 DOM bindings. - * Encoding as specified in a Content-Type header's charset parameter is now - honoured when scripts are loaded. - * Changed InterpreterFactory so that multiple MIME types can be associated - with a given Interpreter. - * text/javascript, text/ecmascript, application/javascript and - application/ecmascript are now all supported as script types for Rhino. - Processing of application/ecmascript is as specified in RFC 4329. - * Improved integration when running under Mac OS X: Squiggle's menu bar - is now at the top of the screen, the application window has a proper - name and functional About/Preferences/Quit menu items, and a Squiggle.app - application bundle can now be created. - * JAR files now have Implementation-* attributes. - * Added an interface for all ImageRenderers to get/set RenderingHints. - -3. Bug fixes - - * SVGMatrix.rotate now takes deg rather than radians. - * Fixed mouseout/mouseover tracking, which regressed some time between - 1.5beta5 and 1.6. - * Fixed misplaced glyph for mixed LTR and RTL text. - * Fixed handling of tooltips from title elements. - * Fixed rendering error (bug 36511). - * Fix for broken event propagation across 'use' element shadow tree boundary. - * Fixed a bug in the handling of 'x', 'y', 'width', 'height', - on feImage elements. - * Fixed bug in EventTarget.{add,remove}EventListenerNS wrapper - for Rhino. - * Fixed memory leak with dynamically added title tooltips. - * Fixed bug with update regions and filters. - * Fixed a problem with feSpotLight and feSpecular lighting (bug 36745). - * Fixed bug with event removal for multiple events and the same target - (thanks Andreas). - * Fixed problem with lowercase 'European' vowels (accented vowels). - * Fixed duplicated fragment identifier bug. - * Fix to allow transcoders that execute onload to work with SVG 1.2 - documents. - * Fix incorrect reporting of modifier key states in DOM UI event objects. - * The broken link image works again now. - * Convert "" to null for namespace URIs given to public DOM interfaces. - * Gradient scaleback is now 0.999 rather than 0.97. - * ttf2svg now emits a document with an SVG namespace declaration. - * Include the o.a.b.ext.awt.image.spi.{ImageWriter,RegistryEntry} service - resource files in the codec jar. (Fixes problems with data: URIs for - images when Squiggle is run from the jars.) - * Fixed problem with ZoomAndPan handling overriding user disabling of - interactors. - * More sensible handling of source 'URLs' in svgrasterizer. - * Greyscale sources are now treated as if they have sRGB Gamma. - * Fixed SVGTextContentElement.getExtentOfChar to use glyph metrics rather - than the glyph shape bounding box. - * Changed Errors to UnsupportedOperationExceptions for unimplemented methods. - * JSVGViewerFrame uses reflection for the Rhino debugger to enable - compilation without Rhino. - * Fixed phantom 'double click' bug. - * Handle 'style' elements added and removed from the document when they are - not at the root of the addition/removal. - * Make CSS engine not throw an NPE for extension elements that don't expose - an OverrideStyleProvider. - * Fixes for text-on-a-path with glyphs who's geometry doesn't "start" at 0. - * Various deadlock fixes. - * Fixed bug where writing TIFF with JPEG compression fails. - * Fixed significant performance bug in creating geometry (it was - parsing the entire path for each entry in the path, O(N^2)). - * Fixed SVGTextContent interfaces on FlowRoot elements. - * Fixed NPE when reloading an SVG 1.2 document quickly. - * Fixed bug where mousing over 'a' elements would result in exceptions. - * Avoid NPEs when loading scripts from file: URIs. - * Fixed flowText regression by rebasing off SVGOMTextPositioningElement. - * radialGradient has a default value of "50%" for 'r' (thanks Tonny). - * Fixed bug in key event dispatching when compiled under JDK 1.3. - * Avoid precision errors in stringification of transform list values - (thanks Nick). - * Unmaximize Squiggle window if the "Automatically resize window when - loading documents" option is turned on. - * Fixed improper rendering of the batik70.svg sample under OS X. - * Fixed synchronization bug in the SVG generator. - -4. Misc - - * Code now compiles under Java 1.5 and 1.6. - * Lots of code/javadoc cleanups. - * New Forrest-based website for Batik. - * New about box/splash screen. - * Visual refresh for Squiggle's toolbar icons and Preferences window. - -1.5.1 -> 1.6 ------------- - -1. Bugzilla problem reports fixed: - - 28035, 28188, 28429, 28432, 28487, 29110, 29891, 30580, 30584, - 30739, 30923, 30925, 30948, 31603, 32108, 32435, 32872, 32951, - 33242, 33733, 33890, 33923, 33986, 34030, 34041, 34115 - - -2. SVG 1.2 Features: - - * All SVG 1.2 elements/features have been moved from - the Batik namespace into the SVG 1.2 namespace (except for - flowText which remains, due to some loss of functionality - with the current flowRoot and potential spec instability). - * Implementation of SVG 1.2 flowRoot element (text flow into - arbitrary regions with bidi support). - * There is now an SVG12CSSEngine which has support for new - properties in SVG 1.2 - - -3. Improvements: - - * Massive performance improvement (>10X) for drawing on Mac OS X. - * Document.getElementById now uses a Hashtable to speedup lookups. - * JavaScript can now be used in an Applet out of the box. - * Added support for 'font' shorthand property. - * Added support for 'deselectAll' SVG DOM call. - * getEncolsureList and getIntersectionList are implemented. - * Added support for get[Screen]PixelUnitToMillimeterX/Y - * SVG DOM getTotalLength, and getPointAtLength are now implemented. - * Support for preserveAspectRatio DOM methods. - * Squiggle browser now has a 'Save As' menu item. - * Can toggle if xml:base should be added to saved SVG. - * Can 'pretty print' saved XML for readability. - * ExtensibleSVGDOMImplementation no longer exists, - the SVGDOMImplementation is now extensible. There is a - new baseclass ExtensibleDOMImplementation that provides - extension capabilities to any DOMImplementation subclass. - As a result the name of the services meta-file has moved to: - 'org.apache.batik.dom.DomExtension' - from: - 'org.apache.batik.dom.svg.DomExtension'. - People with DOM extension will have to update the service file - accordingly. - * ExtensibleDOMImplementation now allows 'extension' elements in - the SVG Namespace (they are always lower priority than 'buit ins'). - * When a new Document is loaded a new BridgeContext is created for it. - As a result each document now get's it's own CSS engine. - * ttf2svg now supports 'auto ranging' so it looks at the font - to decide what to output. - * DOM will now detect when the child passed to insert/remove - * AbstractParentNode will now throw a DOM Hierarchy exception - if you try to append a node as a child of it's self (PR 34030) - * Anti-aliased clips (hqClip patch). This can be disabled by setting - the transcoding hint to vector or print (so content doesn't get - rasterized). PR 29110. - * Control of tiled image rendering based on rendering hint. - Using this hint may greatly increase the amount of memory used. - * The Marker interface now has a 'getCharIndex()' method to - get the index of the character the Mark is associated with. - node is not the child of the node insert/remove is called on. - * DrawImage now defaults color model to sRGB_Unpre if the destination - doesn't include alpha. - * The pattern element now shares one rendering tree across all - references. - * Some improvements for Kerning in SVG Font (faster) - * Arabic diacritics are now positioned relative to the right edge - of the base glyph. Bug 28429 - * Basic DocumentType implementation, if present DOMUtilities will - now emit a proper doctype specification - * GVT Tree walker can now be given any node in the GVT tree and it - walk just that subtree. - * Many places now use getResource as Stream instead of Resource - bundles where localization is not wanted/needed. - * Tweaked UpdateManager repaint scheduling alg. - It now tracks when the rendering goes 'out of date' - with the document and runs runnables until it is out of - them or MIN_REPAINT_TIME is exceeded. - * Arc2D now translated to path with elliptical arc commands - in SVGGraphics2D interface. - * JSVGScrollPane now uses bbox of geometry if no viewBox is provided. - * Refactored the text and flow bridges so make things cleaner. - * Implemented textLength to return the value of - getComputedTextLength when the textLength attribute is not - set. - * Potentially large optimization in BBox generation - * The DOM tree viewer now has an option to hide text nodes that - only contain whitespace. - * The DOM tree viewer now includes the id of an element in the - tree view if it has one. - * Improvements to empty bounds handling, should decrease update areas. - * GVT Render requests are now compressed. This helps when doing - live resize of large documents. - * Some refactoring/restructuring of svggen.XmlWriter to potentially - make it a pretty printing DOM serializer. - * Latest pdf-transcoder from FOP which supports '-dpi' switch. - * ScrollPane now should do a better job of fitting document w/o - scrollbars - * title and desc changes are now dynamically tracked. - * ScriptFactorys now loaded via Services interface. - * Made the JDK image loading Mediatracker static - (so others could use it easier). - * ParsedURL now uses the current Batik version as it's default - UserAgent - * Rationalized Text Selection code. Copy to clipboard is now done - by JGVTComponent only if 'unix style' text selection is requested - (default). - -4. Bug Fixes: - - * Fixed all known memory leaks with loading images. - * Changing documents in JSVGScrollPane now works properly. - * Fixed a small memory leak when changing xlink:href on a - use referencing a local element. - * No longer uses Thread.interrupt. On some JVM's this can confuse the - class loader. - * Adding elements in the 'null' namespace nolonger causes a NPE exception. - * Fixed colorspace error in ColorMatrixRed. - * Line element no longer has a fill associated with it. - * Fixed bug #29416 - problem with empty quotes in CSS. - * Fixed bug #34210 - element selectors are now case sensitive - * Index out of bounds error fixed in linear gradient. - * AOI problem in PrintTranscoder now fixed. - * Null Pointer exception when PrintingTranscoding documents - using SVG fonts is fixed (the BridgeContext was being - disposed of too early). - * PrintTranscoder now uses UserAgent to report exceptions - rather than silently swallowing them. - * Fixed some minor bugs in the GlyphLayout code for flow regions. - * Very minor tweaks in JSVGScrollPane. - * Applied patch 28188, fixed tooltip text & title text, thanks Glen - * Applied patch 28487, fixed enabled/disabled state for - toolbar buttons, thanks Glen - * Fixed bug in text selection (programatically selected text wouldn't - clear properly. - * Fixed bug 23035 - Xlink attributes initialized with wrong values. - * Fixed Bug 28785 - 'a' element not clickable with namespace prefix. - * Bug 30584 - Concurrent Modification believed fixed (couldn't get - test case to fail after fix). - * Bug 29891 - Rasterizer problem if w/h == viewBox w/h - * No more 'flicker' when panning a dynamic document. - * CmapFormat4 now clips charCode 0->65534. - * All Object.wait calls are now in while loops to prevent spurious wakeups. - * DOM keypress events will now be generated for so called - Java 'action' keyEvents (previously only keydown/up were - generated). - * Fixed a bug in the PNG Encoder for some 1,2 or 4 bit/pixel images. - * Fixed bug in PackBits TIFF files with multiple IFD's - * The 'debug' messages are now synced with GUI messages. Also they - are localizable. - * Tweaked the way we generate paths to avoid a bug - in the Mac OS X Java implemention where a close - followed by a moveto didn't join the path properly. - * Fixed width/height change onload bug in transcoders submitted - by Simon Mieth. Thanks! - * Fixed a bug with CSS shorthand properties not being set by presentation - attributes. - * DOMImplementations now return empty documents if - qualifiedName in createDocument is null (PR 32108) - * Fixed 'flashing' with JSVGScrollPane. - * Fixed PR: 30923. Text children now respect display and - visibility properties (including dynamic changes). - * Fixed visibility update bug reported by George Armhold. - * Fixed visibility bug on image elements. - * getBBox should now work per the specification. - a) fill="none" will still give bbox - b) It is now the tight bounds of the geometry - c) It does not include the stroke anymore. - d) When called on 'undisplayed' elements returns null (not sure - what the spec really says about this). - * Modification of use element's width/height now works. - * Fixed potential interrupted bug in the RunnableQueue class. - * The document loader cache now uses soft references to avoid - being a memory leak. - * Improved the xml:space support. - * textPath no longer supports 'position attributes' on it's self - * textPath now supports progression position attributes provided - by parent/child tspan/text nodes. - * systemLanguage, requiredFeatures, requiredExtensions now all fail - to match when given an empty string (as specified by the SVG - specification). Bug #33242 (thanks Rick Graham). - * Fixed potential synchronization issues in JavaScript intervals. - * Small optimization in Event dispatch. - * Removed debug print from SVGOMAnimatedPreserveAspectRatio.java - * Synchronization fix in SoftReferenceCache. - * SAXParser now includes 'ignorableWhitespace' when building the - DOM tree. I also tweaked the way text and CDATA sections are - created. - * UpdateManager is now always the 'source' of UpdateManagerEvents - previously in some cases it was an inner class. - * Fix for masks when using Alpha Premultiplied (Mac OS X). - * Improved consistency of events from the RunnableQueue. - Calling suspend/resumeExecution should now always generate - a runHandler event (although the events may be "compressed" - so suspend/resume may only generate one resume event). - * Fixed bug in handling kerning elements with multiple glyph entries - in g/u 1or2. - * Removed use of 'getTagName' to use 'getLocalName' to avoid issues with - prefixed svg elements. - * Fixed a mistake in the generation of SVG fonts that include - arabic forms (PR 33733) - * Fixed handling of complex paint types (base types with - fallbacks). - * Fixed CSS SVG DOM interfaces for complex paint types - (see bug 33923). Added new test for same. - * Text Selection events are now generated even when the - done event is not over a graphics node. - * The double '#' bug is gone in the SVG Pretty Printer. PR 33890 - * The worst of the 'extra spaces' problem with the pretty printer - is solved. - * Fixed updates to SVG Font based text (PR 34041) - * Bug fix in NumberParser (thanks dvholten) - * Fixed bug 34115 - CSSStyleDecl doesn't collapse properties. - * JSVGCanvas no longer holds cached viewBox so it responds - properly when viewBox is updated in SVG content. - -5. Misc: - - Documentation updates - JavaDoc will now reference W3 and JDK docs - Updated MAINTAIN file - Splash/startup screen now embed font (a little simpler SVG as well). - Some Rhino improvements. - New Tests for bugs. - - Thanks to everyone on batik-dev/users for reporting problems and - working on finding solutions. - -1.5 -> 1.5.1 ------------- -1. Security: - - A script security issue was reported in the Batik Squiggle - browser. Squiggle uses the Rhino scripting engine and some features - of that engine can be leveraged by malicious scripts to gain access - to otherwise protected resources (like the file system). - - The Batik team has worked with the Rhino team to fix the isssue - that was reported and the Batik 1.5.1 patch release addresses the - issue. - -2. Features: - - Rhino JavaScript Debugger now integrated with Squiggle. - Better line numbers in error messages. - Zachary DelProposto's Scroll pane class is added. Allows for - scrollbars on SVG documents. - Cool solitaire examples in SVG. - -3. Performance fixes: - - Parents who have children added/removed no longer invalidate - their entire area. - When a element is removed or CSS properties changed all next - siblings are not repainted unless CSS rules change them. - First event dispatch is much quicker than the past. - Switched to Xerces 2.5.0 to improve performance of data protocol. - Changes to paint properties on text is now _much_ faster. - When using many objects from an external file the file will only - be loaded/parsed once. - Modifying x/y and some viewBox changes on SVG elements is now much - faster. - Better JPEG embedding in PDF. - -4. Conformance: - Batik now passes all non SMIL-Animation tests from the SVG Working - Group beSuite. - - @font-face CSS property and font-face elements are now compliant - with SVG specification. - - Changes to the 'class' attribute now update rendering tree - correctly. - - selectSubString now implemented. - - Dynamic modification of display, and marker properties supported. - SVG 'a' element respects 'preventDefault' on event object. - Pattern element no longer applies object bounding box transform - if viewBox is specified. - -5. Bugs: - - Fullscreen mode (F11) works again. - getExtentOfChar() returns bbox in text elements coordinate system. - SVGPoint now supports matrixTransform in more cases - clientX/Y now correct when target is a text element. - Bugfix in parsing some TrueType fonts fixed. - Now applies the 'all' media type to all content. - Image transcoders default to 400x400 rather than issuing an error - (consistent with viewer). - The properties opacity/filter/masking/pointer-events now work - on SVG elements. - Clearing text selection now works - Zero width/height image elements now work properly. - BBox info is correct for zero width/height items. - Fills/strokes text when text-rendering is set to geometricPrecision - rather than using drawGlyphVector. - getCssText() returns the relative version of URI's - SVG Graphics2D outputs correct rendering hints for text. - TextNodes returns the correct bounds. - Proper text child set as 'target' of events. - Events handled correctly for documents that reference the same - image multiple times. - Image are displayed as 'broken links' instead of being an error. - FeColorMatrix now respects color-interpolation-filters property. - elem.style.setProperty now works for shorthand properties. - Fixed race condition in JSVGComponent.set[SVG]Document. - Fixed several memory leaks dealing with use element. - Glyph element's 'd' attribute uses inherited winding-rule. - SVG 'style' element no longer generates multiple 'xml:space' attrs. - SAXDocumentFactory now generates only one CData node for each - CData section in source document. - Memory leak with addEventListener and objects that ref event target fixed. - Click events now allow a small amount of 'slop'. - Fixed bug in rendering with Double Buffering. - Clicking on the Canvas no longer clears the system clipboard. - No longer recascades elements in use tree from foreign documents - Now supports CSS properties with the max negative 32bit int value - Now supports more JPEG image types. - No longer throws a Class Cast exception when using named colors - as the fallback for icc-colors - clearTimeout, clearInterval no longer throw exceptions for null - objects. - clipPath now respects clip-rule when using 'use' element. - - Bug PRs: 12536, 23030, 23038, 23079, 23177, 24919, 25251, 25463 - - -1.5beta5 -> 1.5 ---------------- - -1. Features: - - - With JDK 1.4 text-rendering="optimizeSpeed" will render - non-anti-aliased hinted text (for axially aligned text). - - - The pointer-events property is now handled correctly for elements - without fill or stroke paint. - - - Improved stroke accuracy when shape-rendering="geometricPrecision" - - - JSVGComponent.setSVGDocument with 'null' now releases all - heavy resources and makes the Canvas display only Background. - - - Many memory leaks fixed. - - - Transcoders and JSVGComponent will now accept any Document - and convert to a Batik SVG Document if needed. - - - Script interpreters are loaded lazily. This means that unless you - use them (by having event attributes or script elements) you - don't need any script engines. - - Performance Improvements: - - - Image drawing is now 5-10x faster, for most raster images. - - - Significant performance improvement for patterns that are - filtered or have filters applied to them (take Batik70 for - example). - - - AbstractParentNode insertNode, removeNode, replaceNode are - now much faster for Parents with many children. - - - Library changes: - - - Updated to the Rhino 1.5R41 library - - Others: - - - Added control of floating point precision used in SVGGraphics2D - (see the org.apache.batik.svggen.SVGGeneratorContext class) - - - Batik now almost never opens image URL's twice. - - - JSVGComponent/BridgeContext now has three levels of interactivity. - STATIC, INTERACTIVE, DYNAMIC. With increasing memory overhead - and build time requirements. - - - Improved test environment with automated memory leak, performance, - threading and interactivity tests. There are now over 1000 tests - in the regard regression test suite. - - - Window.parseXML now returns a Document when no 'host' - Document provided. - -2. Bugs: - - See: http://nagoya.apache.org/bugzilla for details on each bug. - - - 6526 pointer-events does not work for fill="none" stroke="none" - - 6683 JSVGCanvas - Problem adding to JScrollPane - - 6951 see samples/tests/spec/paints/linearGradientLine.svg - - 8854 Fix feImage implementation according to latest SVG 1.0/1.1 c - - 9981 Improve Documentation on Scripting with Java - - 9994 text-decoration:underline is incorrect with tspan elements. - - 12013 Squiggle renders jagged curves/paths 12079 transcoder.wmf - - 13870 Language Code errors - - 14011 problem using rasterizer with the headless option - - 14673 not-so-pretty text rendering - - 14788 TranscoderInput(XMLReader reader) does not seem to be implem - - 14789 TranscoderInput(Document document) is incorrect - - 15348 SVGGraphics2D should not export scientific notation on CSS p - - 17168 SVGGraphics2D has package level protected on DOMGroupManager - - 17863 API to get Version info - - 17965 SVGGraphics2D adds 'font-size' attribute to 'line' and 'circ - - 18143 Removing attribute using Element.removeAttributeNode doesn't - - 18566 JSVGComponent packs its parent window - - 18640 Problem with setSVGDocument - - 18840 A few issues with the Batik source - - 18841 Problems with imports in Batik source - - 19017 error when attempting SVG to PDF conversion - - 19363 zero width on rect element causes error - - 19392 Bug in "org.apache.batik.dom.util.DOMUtilities.java" - - 19865 Exception rendering linked PNG file. - - 20147 JSVGCanvas doesn't function with JInternalFrame - - 20201 incorrect gAMA chunk for sRGB - - 20331 bug on batik SVG DOM implementation on the SVGPathSegArcAbs - - 20332 bug on batik SVG DOM implementation on the SVGPathSegCurveto - - 20811 A rect disabled because of zero width or height doesn't get - - 21125 XML comment cause css parser to abort parsing - - 21259 Drawing on an SVGGraphics2D and then using JPEGTranscoder pr - - 21352 XML comments inside script elements treated as script code - - 21358 Dynamic Update of content referenced by a does not wor - - 21361 Bug on SVGPaint implementation - - 21362 Bug on CSSStyleDeclaration on URI reference - - 21374 Implement conformant Java Handler code - - Viewer now properly displays w/h x/y locations in - 'viewbox' coordinates. - - Fixed dirty regions for nodes that change size then - position in the rendering tree (where the new position - has a different rendering transform). - - Fixed handling Fragment URL's with colon's in them. - - Batik no longer considers all @font-face rules a syntax error. - Batik now just ignores them. - - Fixed use elements in Documents with no base url. - - Runs of RTL Text now work with JDK 1.4. - Nested embed and bidi-override properties should now work. - - Fixed bug setting viewBox on outermost SVG element as - described in: - http://koala.ilog.fr/batik/mlists/batik-users/archives/msg03513.html - - JSVGComponent/Canvas now repaints when it changes size - (even when no viewBox). - - Modifying zero W/H rect, circle, ellipse now works properly. - - Fixed the handling of kerning attribute. - - JSVGComponent.setSVGDocument with a Document that has been - previously viewed in the Canvas now works - - 'style' and 'script' elements no longer include the contents - of XML Comments (unless inside a CDATA block). - - Fixed a with absolute x/y attributes in non-text - progression direction. - - Fixed JSVGComponent when it's working threads are - interrupted. - - RhinoInterpreter once again binds the Global Object - as 'window' - - -3. Extensions: - - - Updated multiImage element to match WD. - - -4. Documentation: - - - Updated the FAQ with frequent questions on UpdateManager, DOM - updates and visual updates. - - - Updated the implementation status page and the home page. - - -1.5beta4b -> 1.5beta5 ---------------------- - -1. Features: - - Library changes: - - - Xerces 2.3 is now the default parser. The parser can still be controlled - through the org.apache.batik.util.XMLResourceDescriptor class. - - ** NOTE ** - - While the general performance of the Xerces 2.3 parser seems equivalent - to those of the Crimson parser used previously, there is a notable exception - in the handling of long attributes. This makes a very visible difference - for SVG content that uses embeded images through the 'data:' protocol which - can be extremely slow with Xerces 2.3. The bookOfKells.svgz example, which - used the data: protocol for rather long images has been removed from the - distribution as it does not load in a reasonable amount of time when using - Xerces. - - - Rhino version has been updated from 1.5R3 to 1.5R4 allowing to fix - BR #11968 (DOM access functions should return ECMAScript strings). - - - Removed SAX and DOM sources from the Batik project. Now use xml-apis.jar - from xml-commons. - - Others: - - - currentScale/Translate now implemented (get and set). - - - Implemented getScreenCTM, fixed getCTM (SVGLocatable) - - - onzoom, onscroll, onresize events are now implemented. - - - Integrated pdf-transcoder from FOP. - - - Ctrl-K/L work in fullscreen mode. - - - initial support for SVGList ( provided for SVGPointList in - and , SVGPathSegList in , SVGLengthList - in textual elements, SVGTransformList in graphical elements ) - - - RFE #12735 : added support for dynamic modifications of 'xlink:href' in image element - - - Now skips reading the SVG DTD unless validation - is turned on (improves load times for small docs). - - - glyph-orientation-horizontal now works. - - - linearGradient's can now be anti-aliased (radial gradient - anti-aliasing also improved). - - - PNG Transcoder can now produce 1,2,4 & 8 bit indexed PNG's. - - - rasterizer can now be used in headless mode (JDK 1.4) - - - JPEG files now have X/YDensity set according to -dpi option. - - - Batik Docs now include a dependency graph for the jar files. - - - In ECMAScript, add the ability to pass an Object instead of a - Function to the Window.getURL() method in which case the - operationComplete method is called once the URL is retrieved. - - - SVGUserAgent now controls the default font-family - - - Added max-width and max-height support in the rasterizer infrastructure - (contribution by Henri Ruini, Henri.Ruini@nokia.com) - - - Improvements to the WMFTranscoder by Luan O'Caroll - - - Added better error reporting for external scripts: errors now include the uri - of the external scripts in addition to the line number which is convenient - when an SVG file references multiple external scripts. - - - Modified the way SVG public identifiers are mapped to system identifiers. - The resource file now contains the mapping to the correct SVG DTD instead - of only containing the allowed SVG 1.0 system identifiers for a hard - coded DTD. - - - Added support for cursors. - -Bug Fixes: - - - clientX/Y values in MouseEvents are now returned in screen - pixels (it had been the viewBox coordinate system which was - convenient but wrong and problematic for some cases). - - - Changed default extension for TIFF files to '.tif' from '.tiff'. - - - Fixed bugs in screen updating when the size/location of the - root graphics node changed, and when transform on group - changes after bounds on a child. - - - ToolTips no longer 'hang around' under JDK 1.4.1 - - - The JSVGCanvas no longer steals focus and pops forward whenever - the cursor passes over the canvas. - - - The JSVGCanvas will no longer thrown an exception if an SVG - document is set prior to the component's size being set. - - - Text anchor for vertical text. - - - For corrupt/incomplete JPEG images now shows what it can. - - - Fixed bug with Indexed PNG's that have a bKGD chunk. - - - getRelatedTarget fixed for mouseout event. - - - glyph-orientation-horizontal/vertical no longer require a unit - as per the SVG specification. - - - Fixes for 'jar' protocol. - - - Fixed compressed Tiff writing. - - - Missing Glyph's are now rendered correctly. - - - Text selection now works better with altGlyphs. - - - PrintTranscoder no longer scales 'real world' units wrong. - - - Fixed a bug involving the 'use' element with a width/height in - an SVGFont referenced from external documents. - - - Collaboration with Philipe Converset (Qarbon) on an extension to define - margins in filter regions. This is now supported in the Batik namespace. - -2. Bugs: - - 12389 Focus issue in Squiggle's URL text field - 12121 Cursor in URL field disappears - 12168 MarkerShapePainter delivers wrong PaintedArea - 12239 [PATCH] Moved some method local variables into class - 12954 add support for stroke-width:0 - 15162 PNGTranscoder gives error message about TIFF transcoder - 17167 stroke-dashoffset does not support negative length - 13713 element fails when using percentage values x/y coords - 17183 baseline-shift doesn't refer to parent "line-height" - 15063 Version-dependent code in package org.apache.batik.gvt.font - 12736 Allow non-element nodes to be added to g and svg elements. - - - Added Units resolutions to CSS rects - - - 'd' and 'points' can now be empty on , and - - - - Now support the transform attribute on the element - - - Fixed class loader delegation bug in RhinoClassLoader - - - Patch from Keiron Liddle fixing PNGTranscoder KEY_INDEXED hint type - issue (was Boolean instead of Integer) - -3. Extensions: - - - Binary distributions now include jar files that can display - extensions. - - - The multImage element can now reference SVG images as well - as raster images. - - - flowText now supports vertical-align. - - - flowText now uses 'flowRegion' and 'rect' to describe flow - areas. - -4. Documentation: - - - Status of Batik implementation of SVG DOM. - - - Diagram showing the various Batik jar files and their relationships. - - -1.5beta4 -> 1.5beta4b ---------------------- - -This is a patch release fixing a bug on linking. - -1.5beta3 -> 1.5beta4 --------------------- - -1. Features - - - Squiggle Browser: - - - the F11 key lets users enter the full screen mode or exit the - full screen mode if they are already in that mode. - - - the Browser can now handle XML files which contain a stylesheet - declaration referencing an XSL transformation. If that transformation - generates an SVG document, Squiggle will display it. - - By default, this feature is disabled because it requires that - the user either uses the JDK 1.4 (or greater) version (which at - this time is not a requirement for Batik) or that an XSL transformation - engine (such as Xalan) be in the classpath. - - To enable the feature, uncomment the following line (i.e., remove the '#'): - - #org.apache.batik.apps.svgbrowser.XMLInputHandler - - in the: - - resources/META-INF/services/org.apache.batik.apps.svgbrowser.SquiggleInputHandler - - file. - - - Scripting: - - - Added the ability to use an ECMAScript object providing an handleEvent - method for the listener argument of the addEventListener method on DOM objects - (previously only ECMAScript functions were accepted as parameter). [RFE9149] - -2. Bug Fixes - - - Images - bounds/hints now updated correctly when changed via script - - Local refs now work with null Document URL. - - Double buffered rendering now updates correctly on Mac OS X. - - ParseXML no longer assumes doc is SVG. - - Squiggle can now do Http authentication. - - SVG Font bounds fix - - Text layout fix (anchor and textLength) - - Adding/Removing children no longer invalidates entire parent region. - - handling of position attributes (x,y,dx,dy,rotate) on emtpy tspans has been fixed. - - Fixed improper handling on - - Removed unnecessary font matching with which can be found - - 'stroke-dasharray' now works with units, - - fixed bugs (CSS !important rules, DOM replaceChild on the root element, - SVG paint parsing, CSS percentages). - - -1.5beta2 -> 1.5beta3 --------------------- - -1. Features: - - - Squiggle Browser: - - - now keeps a history of recently visited URIs - - - offers more control over the security features - - - Enhanced Security Support: - - - downloading of all external resources can now be - controlled through the UserAgent. This includes - scripting (as before) but also , , and - all elements which may reference external resources - (over 15). - - - users security policy now takes precedence over the - application policy. Users can set the java.security.policy - system property when starting a Batik application and it - will take precedence. - - - Interactivity and Scripting Support Improvements: - - - filter, mask, gradients, clip, pattern and marker are now - updated when the geometry of the referencing graphical - element is dynamically changed. - - - implementation of keyboard events (KeyEvents from DOM Level 2 - Working Draft). In the near future, the batik team will - implement the TextEvents from the DOM Level 3 Events module. - - - Newly supported elements (can now be modified by scripts): - , and element children (such as ); - - - Support for addition/removal/modification of stylesheets - - - Misc: - - - external scripts can now be gzipped. - - - added getPixelUnitToMillimeter to UserAgent classes - NOTE: the getPixelToMM and getPixelToMillimeter methods will be - removed after 1.5b3 is released! - - - Improvements in the support for the extension - - - Added support for attribute/id/adjacent selector and :first-child - dynamic updates, - -2. Bug Fixing: - - - #1075, #4834, #5233, #5347, #5806, #6642, #6683, #7053,#8330, #9740, - #9058, #9067, #9304, #9429, #9520, #9779, #9804, #9272, #9276, - - bug in feColorMatrix - - DOM: getElementByTagName, invalidateElementsByTagName, cloneNode(false) - - mouseout bug on fixed - - File->Open dialog bug on JDK 1.4 fixed. - - Memory leak fixes - - ttf2svg now emits kern elements with the proper sign - - MultiImage now respects xml:base - - Fixed mouse location bug - -3. Documentation Update: - - - Many additional links have been added to the Batik documentation - as well as improvements in its structure and content, thanks to - the work of Robert Di Blasi. - -1.5beta1 -> 1.5beta2 --------------------- - -** Note on the new security support ** - -- Scripts are now run in a sand-box by default for the Batik sample - applications (the Squiggle SVG Browser and the Rasterizer). Users of - the SVG toolkit who what to run scripts securely need to add - security support in their application and may use the work done for - Squiggle as an example - (e.g., see the org.apache.batik.util.ApplicationSecurityEnforcer class). - -- There is a known limitiation: scripts loaded from a 'file:' url - cannot access (i.e., load files) under the same root. This is not - true for scripts loaded from a server (e.g., 'http:' urls). - -1. Features: - - - Scripting support for styling properties: - - - Most of the CSS properties and style attributes can now - be changed dynad:/work/dev/svg/apache/builds/batik-1.5beta3/mically. See: - http://xml.apache.org/batik/supportedProperties.html - - - Added support for style and class attributes dynamic updates - - - - DOM support: - - - Implementation of SVGLocatable including SVGMatrix - - - All class members of type: SVGLength now works on most of the - graphical elements (rect.x.baseVal.value) - - - Implementation of CSS DOM (getStyle, getComputedStyle...) - - - - Events/Interactivity: - - DOMFocusIn, DOMFocusOut and DOMActivate event types are not supported - - - - Security: - - - Secure scripting is now in place. Scripts in ECMAScript or - Java code are run in a sand-box by default. The Batik browser - (called Squiggle), has the following security options: - . secure execution of scripts can be on or off. - . scripts for a given language can be disabled/enabled. - . scripts can be constrained to come from the same origin - as the document referencing them. - In the Squiggle SVG browser, the security options can be set - through the Preferences dialog, in the browser options panel. - - - - Misc: - - - xml:base is now supported for the image element. - - - extension element that flows text into multiple boxes. - Trying to track the SVG 1.1 Working Group on this element. - - - getURL, parseXML supported in the Window object. - - - - Testing: - - - Improved test infrastructure. There are new tests for handling - automatic regression testing of scripting features and there are - more tests (801 now) in the regard regression test suite. - - -2. Bug Fixing: - - - Fixed bugs with textPath w/ text-anchor, and textPath w/ multiple - trailing tspan elements. - - - Work around for RenderingHints when Batik Jars loaded multiple times - in the same JVM (through different class loaders). - - - Fixed a bug with X/Y Resolution for Tiff. - - - UIEvents are not dispatched properly on children (...) - - - is now supported on element children - -1.1.1 -> 1.5beta1 ------------------ - -** Note on enhanced scripting support ** - -- Support for DOM Core and DOM Events (Mutation events and UI events) - -- Limitations: - - No support for dynamic modification of CSS properties. - In particular, setAttributeNS of presentation attributes - such as 'fill' or 'stroke' or modification of the 'style' - attribute are not supported. - -1. Features: - - Enhanced scripting support: it is now possible to modify - SVG documents through scripting - - Tiff Transcoder now takes FORCE_TRANSPARENT_WHITE hint. - - Tiff Transcoder now writes resolution tags. - - Implementation of SVG 1.1 solidColor element (in Batik extensions) - - Implementation of multiImage element (a Batik extension). - - Event compression mecanism (e.g., concatenates mouseMove events) - -2. Bug Fixing - - - textLength now works in all cases except nested textLengths. - - 'image' element now respects xml:base. - - Renderer now reuses image buffers more often. - - Speed improvements in cases with lots of tspans. - - Filtered Raster Images now _much_ faster. - - Things mostly work with current Mac OS X JVM (still some trouble with - images/filters). - - Applying a ICC Profile no longer messes up alpha channel in some cases. - - PNG Transcoder now always writes sRGB chunk. - - feImage image positioning fix - - bridge fix, - - SVG generator export fix - - -1.1 -> 1.1.1 Release --------------------- - -1. Bug fixing: - - - dx/x and dy/y now work when combined. - - clip-path now takes transforms into account - - AbstractRable constructors problem fixed. - - Put in workaround for worst of Mac OS X text problems (layout - still isn't 100% correct in most cases). - - Removed code that is no longer needed in GlyphLayout - - Fixed the last text layout issues on Mac OS X (GlyphVector was - returning the metrics for the first char for all chars in the vector. - We now use the difference in defaultGlyphPositions to get the - character advances). - - Fixed JViewerFrame issue with large (width/height) documents. - -2. Improvements - - Text bounds computation is now much faster - -1.1rc4 -> 1.1 Release ----------------------- - -1. Bug Fixing and Improvements - - - Code factorization in parsers. - - Parsers bug fixing. - - Added examples (maps, bookOfKells example, sunRise, mathMetal). - Maps are a contribution of Andreas Neumann, - MathMetal is a contribution of Christophe Held. - - Added default xmlns and xmlns:xlink on root in generator - - Integrated Ant task contribution from Henri Ruini - - Improved error dialog (now includes details with the error stack trace). - - Printing fix. - - text-anchor fix. - -1.1rc3 -> 1.1rc4 Release ------------------------- - -1. Features: - - - rewrite of rasterizer thanks to Henri Ruini's contribution - - improved image handling strategies in the SVG generator thanks - to Paul Evenblij's contribution. - - 'requiredFeatures', 'requiredExtensions' and 'systemLanguage' on - graphical elements - - anchor on raster images and SVG images now works properly - - anchor inside a SVG image now works properly - - inside or is now displayed - - many tests added (transcoder...) - - SVG viewer: added dialog box at start up time while loading classes - - SVG viewer: limited number of files in history - -2. Bug fixing: - - - memory leak fix - - DOM core serialization - - Parsing of CSS comments - - SVG generator fixes (bug 4945 and 4389) - - rasterizer fixes - - text now works with JDK 1.4b3. Remaining issue with - BufferedImages. - -3. Improvements: - - - general performance improvements in the build and rendering - phases of the viewing component (for example float parsing - has been improved). - -1.1rc2 -> 1.1rc3 Release ------------------------- - -1. Features: - - Support for xml:base - - TextSearch dialog is available (with a zoom option) - - Full support for Alternate Stylesheets - - Full support for CSS Media (including a way to define custom media) - - Changed Text Selection UI. (selectable in the preference dialog) - Added Text Selection API to GVT & swing packages - - KeyStroke on the JSVGCanvas (for pan and zoom using keyboard) - - SVG Font: The font lookup now takes into account namespaces - - Provide a way to set the quality of an exported JPEG image - - Printing now uses the CSS print medium - - More complete handling of partial URLs - - Two new extensions solidColor (a single color 'paint server' acts - similar to the gradients and pattern fills/stroke), & paintSwitch - similar to a switch element but children are paint servers instead - of graphical elements. - -2. Bug fixes: - - Fix in gradient element boundary conditions - - Fix and performance improvements in lighting filters - - Fix in PNG encoding for BufferedImage' subimages. - - feDisplacementMap fix (array out of bound exception) - - font lookup now uses namespace properly - - 'enable-background' now work on element - - zero length on , and disable the rendering - - linear gradient with x1=y1=x2=y2 - - printing now supports SVG URI fragment - - Javadoc improvements and clean-up - - Source clean-up - - DOM: getElementsByTagNameNS now works properly - - SVGDOM: huge cleanup of the implementation - (preparation for dynamic features) - - CSS parser bug fix - - Bridge: 'overflow' on SVG should now work properly - - GVT: cleanup the API - GraphicsNodeRenderContext is now obsolete - - -3. Testing - - - Reorganized tests (see samples/tests subdirectory) - - Improved test reporting (i.e., better HTML report) - - Simplified test infrastructure configuration files. - - Lots of new tests (see samples/tests/structure/styling and - samples/tests/spec/structure for examples) and - samples/batikCandy.svg. - - -1.1rc1 -> 1.1rc2 Release ------------------------- - -1. Bug fixes: - - - 'preserveAspectRatio' now works properly on both raster and SVG images - - bug fix with the 'clip' property on , , - - thumbnail bug fix (sometimes the area of interest became hidden) - - filename filter added to the file selection dialog in the svgbrowser when - exporting as PNG and JPG - - Infinite loop removed. Elliptical arc may cause an infinite loop if the end - point of the arc was the same than current point in the datas. - - SVGGraphics2D can now generates SVG Font on demand - -2. Improvements: - - - Added new custom filter extension (look at the samples/extensions/histogramNormalization.svg) - - Added tooltips on and . - -1.0 -> 1.1rc1 Release ---------------------- - -1. Enhancements: - a. HTTP headers fields (useragent/accepted...) now implemented. - b. Anti-aliased gradients (when color-rendering set to quality). - c. Small patterns are now much faster - d. Ability to flush cached image data. - e. full horizontal and vertical kerning now implemented for SVG fonts - f. added support for orientation and lang attributes - g. improved support for Arabic text, includes handling of Arabic shaping - and ligatures for both SVG and system fonts - h. improved text selection - i. improved text rendering speed - -2. Bug fixes: - a. PNG files now use the proper gamma when reading/writing - b. Off by one bug in image rendering fixed (background shows - through on the left and top of image). - c. Fixes in Base64 data handling (encoding/decoding) - d. Absolute URL's shouldn't require document URI. - e. color-interpolation-filters should now work :) - f. fixed bug with font sizes < 1 - g. fixed problems in text chunk algorithm - h. fixed bug with empty text nodes - i. text decorations are now handled properly - j. bidirectional text (including selection of it) is now handled properly - k. fixed problem with alignment of vertical text - l. fixed problem with em and ex unit conversion when font size - is not a float value (eg medium) - -3. Misc: - a. Now have automated tests for base64 - b. Now have automated tests for ParsedURL - c. added some more test files for text and fonts - -beta2 -> 1.0 Release ---------------------- - -1. Completed SVG Font Support. - -2. Added vertical Text Support. - -3. Major rework of the Batik documentation. - -4. Added thumbnail - -5. Bug fixes. - -beta2rc9 -> beta2 ------------------ - -1. Contributions - - a. New contribution of a True Type Font to SVG Font converter that allows - a set of characters from a True Type Font to be converted to the - SVG Font format. This contribution was made by David Schweinsberg - of SteadyState (david@steadystate.co.uk). This contribution comes at - the right time (i.e., as we just added SVG Font rendering suppor). - -2. Improvements & new features - - a. SVG Font support. Initial revision of the soon complete support of - SVG Fonts. - - b. New image encoder/decoder infrastructure. This allows a flexible - handling of new raster image formats. - - c. Improved PNG encoder/decoder which now support the gamma chunk - properly. - - d. Additional tests for SVGGraphics2D. - - e. Additional samples (mostly new SVG Font support examples). - -beta2rc8 -> beta2rc9 --------------------- - -a. Polishing of existing features. -b. Bug fixes. -c. Improved test infrastructure. - -beta2rc7 -> beta2rc8 --------------------- - -1. Improvements - - a. Full blown in-bound and out-bound linking support. See the - two new linking examples in the samples/test directory. - - b. Improved CSS error handling. - - c. New test infrastructure. - - d. Beanified SVG JComponent: see JSVGCanvas. - - e. Enhanced features in SVGGraphics2D to manage style properties. - - e. Improved error handling in SVGGraphics2D - -2. Bug fixes - -beta2rc6 -> beta2rc7 --------------------- - -1 - SVG Viewer Improvements - - a. Added support for double buffering (controllable by an option). - -2. General - - a. Added line-number in error messages when parsing invalid - SVG document. - b. Maintenance and Bug fixing. - c. JSVGCanvas is now a JavaBean which can be easily configured - in IDE tools to add SVG viewing support in an application. - d. Support for rendering hints such as text-rendering and - shape-rendering. - -beta2rc5 -> beta2rc6 --------------------- - -1 - new implementation of the swing component and viewer. - - a. it is now possible to interrupt while loading, building or painting - b. rotations are now applied on the image in real time. document is - repainted when the mouse button is released. - c. real time zoom on the image with SHIFT+BUTTON 2 Drag - d. progressive rendering has been improved - e. toggling debug traces on/off to see performance is now possible - -2 - new implementation of the bridge package - - a. code cleanup - b. percentages are now handled correctly (both for xml attributes and CSS - properties - samples/tests/percentagesAndUnits.svg) - c. error handling has been improved - (line number will be available soon) - d. the building phase is now 30% faster - e. bug fix with (samples/tests/pattern*.svg) - f. is now conformed to the current SVG spec (as of March 15) - g. percentages are now handled correctly on the outermost SVG element (need - to do the same for the ImageTranscoder) - - -3 - Transcoders. There are two new transcoders: - - a. WMF -> SVG Transcoder. This is a contribution to the Batik project from - Luan O'Caroll (Luan.O'Carroll@boimail.com). You can run the transcoder on - a set of Windows MetaFile (WMF) using the - org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder application. - - b. Printing Transcoder. This implementation of the Transcoder interface will - print a set of SVG document to the default printer (see - org.apache.batik.transcoder.print.PrintTranscoder. - -4 - Misc. - - a. support for System colors (see: samples/tests/systemColors.svg) - - b. Creating custom Graphics2D implementation is now easier. A generic part of - the SVGGraphics2D has been moved into a new package: - org.apache.batik.ext.awt.g2d. - This new package facilitates the creation of transcoders that will convert - SVG documents to an arbitrary format by providing a Graphics2D implementation - for that format that Batik can use to draw an SVG document (Batik can use - a Graphics2D to paint an SVG document). - -NOTE: Known regressions. - - a. next, previous and thumbnail have been momentarily removed from the viewer. - b. error messages are printed in the console and not in a dialog. - c. the partial internal linking support has been removed until - a full implementation of linking can be done. - d. printing has not been reintegrated into the new viewer. - e. regressions may appear for scripting as it has been added in a hurry for - this release. A clean pass will be done soon. - f. text regression on tspan handling where dx/dy are temporarily not working. - -beta2rc4 -> beta2rc5 ---------------------- - -a. Text improvements. -b. Improved rendering (now uses tiling for faster panning). -c. Bug fixing. - -beta2rc3 -> beta2rc4 --------------------- - -a. Handling of overflow property on -b. Filter and pattern optimizations -c. Color profile support -d. GVT optimizations - -beta2rc2 -> beta2rc3 --------------------- - -a. Handling of the visibility property -b. Handling of references on gradients, patterns and filters -c. Baseline shift on text -d. Full support for markers. -e. Optimizations in filters and GVT. -f. Bug fixing (e.g., stroke's dash array) - -beta2rc1 -> beta2rc2 --------------------- - -a. A lot of new text support (text length, letter and word spacing..) -b. Some support for markers (not complete yet, but should be complete - shortly, probably by next week). -c. Some support for views (in linking). -d. Cleaned up bridge code. -e. Improvements in the filtering code (there a some minor regressions - which will soon be taken care of). - -beta1 -> beta2rc1 ------------------ - -a Improved text support -b. Full filter implementation. -c. New Transcoder API. -d. Simplified package organization diff --git a/lib-external/batik/LICENSE b/lib-external/batik/LICENSE deleted file mode 100644 index 3e4e3d0040..0000000000 --- a/lib-external/batik/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/lib-external/batik/NOTICE b/lib-external/batik/NOTICE deleted file mode 100644 index 662188f357..0000000000 --- a/lib-external/batik/NOTICE +++ /dev/null @@ -1,18 +0,0 @@ -Apache Batik -Copyright 1999-2007 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -This software contains code from the World Wide Web Consortium (W3C) for the -Document Object Model API (DOM API) and SVG Document Type Definition (DTD). - -This software contains code from the International Organisation for -Standardization for the definition of character entities used in the software's -documentation. - -This product includes images from the Tango Desktop Project -(http://tango.freedesktop.org/). - -This product includes images from the Pasodoble Icon Theme -(http://www.jesusda.com/projects/pasodoble). diff --git a/lib-external/batik/README b/lib-external/batik/README deleted file mode 100644 index f855cb60bb..0000000000 --- a/lib-external/batik/README +++ /dev/null @@ -1,77 +0,0 @@ - - A P A C H E B A T I K - - What is it? - ----------- - - Batik is a Java based toolkit for applications which handle - images in the Scalable Vector Graphics (SVG) format for - various purposes, such as viewing, generation or - manipulation. - - The project's ambition is to give developers a set of core - modules which can be used together or individually to - support specific SVG solutions. Examples of modules are - an SVG parser, an SVG generator and an SVG DOM - implementation. Another ambition of the Batik project is to - make it highly extensible (for example, Batik allows the - developer to handle custom SVG tags). Even though the - goal of the project is to provide a set of core modules, one - of the deliveries is a full fledged SVG Viewer - implementation which validates the various modules and - their inter-operability. - - In a nutshell, Batik provides building blocks that developers - can assemble in various ways in their Java technology - applications to generate, parse, view or convert SVG - contents. For example, Batik contains a Swing component - that can add SVG viewing capability to all Java technology - applications. Batik can also be used to generate SVG on a - client or on a server, and Batik can convert SVG content - into other formats such as JPEG or PNG. Batik's goal is to - make it easy for application developers to handle SVG - content for various purposes, client-side or server-side. - - - Where is it? - ------------ - - The home page for the Apache Batik project can be found in the Apache XML - Project web site (http://xmlgraphics.apache.org/batik/). There you also find - information on how to download the latest release as well as all the other - information you might need regarding this project. - - - Requirements - ------------ - - o A Java 1.3 or later compatible virtual machine for your operating system. - - Optional Libraries - ------------------ - - By default, Batik includes a scripting engine for ECMAScript. It is possible - to add support for additional scripting languages (Python and TCL). - - See http://xmlgraphics.apache.org/batik/install.html#optionalComponents for - details. - - Installation Instructions and Documentation - ------------------------------------------- - - Read the Install page at http://xmlgraphics.apache.org/batik/install.html - for the installation instructions. - - Look for the most updated documentation on the Apache Batik web site under - the Apache XML Graphics Project (http://xmlgraphics.apache.org/batik/). - - - Licensing and legal issues - -------------------------- - - For legal and licensing issues, please read the LICENSE and NOTICE files. - - Thanks for using Apache Batik. - - The Apache XML Graphics Project - http://xmlgraphics.apache.org/ diff --git a/lib-external/batik/batik-rasterizer.jar b/lib-external/batik/batik-rasterizer.jar deleted file mode 100644 index 6700b134bd..0000000000 Binary files a/lib-external/batik/batik-rasterizer.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-anim.jar b/lib-external/batik/lib/batik-anim.jar deleted file mode 100644 index 6913e421c9..0000000000 Binary files a/lib-external/batik/lib/batik-anim.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-awt-util.jar b/lib-external/batik/lib/batik-awt-util.jar deleted file mode 100644 index e64605af88..0000000000 Binary files a/lib-external/batik/lib/batik-awt-util.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-bridge.jar b/lib-external/batik/lib/batik-bridge.jar deleted file mode 100644 index 62c10bae3d..0000000000 Binary files a/lib-external/batik/lib/batik-bridge.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-codec.jar b/lib-external/batik/lib/batik-codec.jar deleted file mode 100644 index 0a83c6ff19..0000000000 Binary files a/lib-external/batik/lib/batik-codec.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-css.jar b/lib-external/batik/lib/batik-css.jar deleted file mode 100644 index c1f1c9a885..0000000000 Binary files a/lib-external/batik/lib/batik-css.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-dom.jar b/lib-external/batik/lib/batik-dom.jar deleted file mode 100644 index 32d5b46d05..0000000000 Binary files a/lib-external/batik/lib/batik-dom.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-ext.jar b/lib-external/batik/lib/batik-ext.jar deleted file mode 100644 index 8c904e1f2a..0000000000 Binary files a/lib-external/batik/lib/batik-ext.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-extension.jar b/lib-external/batik/lib/batik-extension.jar deleted file mode 100644 index 106e4ac3cb..0000000000 Binary files a/lib-external/batik/lib/batik-extension.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-gui-util.jar b/lib-external/batik/lib/batik-gui-util.jar deleted file mode 100644 index bf8c8441af..0000000000 Binary files a/lib-external/batik/lib/batik-gui-util.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-gvt.jar b/lib-external/batik/lib/batik-gvt.jar deleted file mode 100644 index ee47ec8258..0000000000 Binary files a/lib-external/batik/lib/batik-gvt.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-parser.jar b/lib-external/batik/lib/batik-parser.jar deleted file mode 100644 index 286b3799c3..0000000000 Binary files a/lib-external/batik/lib/batik-parser.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-script.jar b/lib-external/batik/lib/batik-script.jar deleted file mode 100644 index 433f02e67c..0000000000 Binary files a/lib-external/batik/lib/batik-script.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-svg-dom.jar b/lib-external/batik/lib/batik-svg-dom.jar deleted file mode 100644 index b4c8a620bb..0000000000 Binary files a/lib-external/batik/lib/batik-svg-dom.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-svggen.jar b/lib-external/batik/lib/batik-svggen.jar deleted file mode 100644 index 4d6bb14417..0000000000 Binary files a/lib-external/batik/lib/batik-svggen.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-swing.jar b/lib-external/batik/lib/batik-swing.jar deleted file mode 100644 index 93e5d0f335..0000000000 Binary files a/lib-external/batik/lib/batik-swing.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-transcoder.jar b/lib-external/batik/lib/batik-transcoder.jar deleted file mode 100644 index 0f2f7cd358..0000000000 Binary files a/lib-external/batik/lib/batik-transcoder.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-util.jar b/lib-external/batik/lib/batik-util.jar deleted file mode 100644 index 86d75e70f2..0000000000 Binary files a/lib-external/batik/lib/batik-util.jar and /dev/null differ diff --git a/lib-external/batik/lib/batik-xml.jar b/lib-external/batik/lib/batik-xml.jar deleted file mode 100644 index d05eb25f77..0000000000 Binary files a/lib-external/batik/lib/batik-xml.jar and /dev/null differ diff --git a/lib-external/batik/lib/js.jar b/lib-external/batik/lib/js.jar deleted file mode 100644 index ccad3cc1bf..0000000000 Binary files a/lib-external/batik/lib/js.jar and /dev/null differ diff --git a/lib-external/batik/lib/pdf-transcoder.jar b/lib-external/batik/lib/pdf-transcoder.jar deleted file mode 100644 index 5476969287..0000000000 Binary files a/lib-external/batik/lib/pdf-transcoder.jar and /dev/null differ diff --git a/lib-external/batik/lib/xalan-2.6.0.jar b/lib-external/batik/lib/xalan-2.6.0.jar deleted file mode 100644 index 79de61d7ab..0000000000 Binary files a/lib-external/batik/lib/xalan-2.6.0.jar and /dev/null differ diff --git a/lib-external/batik/lib/xerces_2_5_0.jar b/lib-external/batik/lib/xerces_2_5_0.jar deleted file mode 100644 index c6455ee34c..0000000000 Binary files a/lib-external/batik/lib/xerces_2_5_0.jar and /dev/null differ diff --git a/lib-external/batik/lib/xml-apis-ext.jar b/lib-external/batik/lib/xml-apis-ext.jar deleted file mode 100644 index a7869d68aa..0000000000 Binary files a/lib-external/batik/lib/xml-apis-ext.jar and /dev/null differ diff --git a/lib-external/batik/lib/xml-apis.jar b/lib-external/batik/lib/xml-apis.jar deleted file mode 100644 index d42c0ea6cf..0000000000 Binary files a/lib-external/batik/lib/xml-apis.jar and /dev/null differ diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml index c02064ba01..daa7637fb6 100644 --- a/nbproject/build-impl.xml +++ b/nbproject/build-impl.xml @@ -20,6 +20,7 @@ is divided into following sections: --> + @@ -1250,12 +1251,12 @@ is divided into following sections: - + - + + + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.desktop/sun.awt=ALL-UNNAMED + --add-opens java.desktop/sun.java2d=ALL-UNNAMED + --add-opens java.desktop/sun.awt.image=ALL-UNNAMED + + + + + + + + + org.jogamp.jogl + jogl-all + ${jogl.version} + + + org.jogamp.jogl + jogl-all + ${jogl.version} + natives-macosx-universal + + + + + + org.jogamp.gluegen + gluegen-rt + ${gluegen.version} + + + org.jogamp.gluegen + gluegen-rt + ${gluegen.version} + natives-macosx-universal + + + + + + org.gdal + gdal + local-wwj + system + ${project.basedir}/gdal.jar + + + + + + gov.nasa.worldwind + vpf-symbols + local + system + ${project.basedir}/vpf-symbols.jar + + + + + + com.fasterxml.jackson.core + jackson-core + 2.18.2 + + + + + + org.junit.jupiter + junit-jupiter + 5.11.4 + test + + + + + + + src + test + + + + + src + + **/*.java + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + 25 + UTF-8 + + true + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + ${jogl.jvm.args} + + + true + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.4.1 + + java + + -Xmx1024m + + --add-opens + java.base/java.lang=ALL-UNNAMED + --add-opens + java.desktop/sun.awt=ALL-UNNAMED + --add-opens + java.desktop/sun.java2d=ALL-UNNAMED + --add-opens + java.desktop/sun.awt.image=ALL-UNNAMED + + -classpath + + + ${exec.mainClass} + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + add-functional-test-sources + generate-test-sources + + add-test-source + + + + testFunctional + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.4.2 + + + + true + + + NASA WorldWind Java + ${project.version} + + + + + testData/** + + + + + + + + + + + rasterize-milstd2525 + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.1.0 + + + + + rasterize-milstd2525-symbols + generate-resources + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + zip-milstd2525-symbols + package + run + + + + + + + + + + + + + + org.apache.xmlgraphics + batik-all + 1.17 + + + + xml-apis + xml-apis-ext + 1.3.04 + + + + + + + + + diff --git a/run-demo.bash b/run-demo.bash index 1512dc618a..82bbd5946e 100755 --- a/run-demo.bash +++ b/run-demo.bash @@ -39,7 +39,14 @@ else fi # -# Run a WorldWind Demo +# Run a WorldWind Demo via Maven. # -echo Running ${WWDEMO} -java -Xmx1024m -classpath ./worldwind.jar:./worldwindx.jar:./gdal.jar:./jogl-all.jar:./gluegen-rt.jar ${WWDEMO} \ No newline at end of file +# Maven resolves the full classpath (JOGL 2.6.0, GlueGen 2.6.0, GDAL, etc.) +# from the project dependencies declared in pom.xml, so no manual classpath +# management is required here. +# +# The --add-opens flags are declared in the exec-maven-plugin configuration +# in pom.xml and are forwarded automatically to the forked JVM. +# +echo "Running ${WWDEMO}" +mvn --quiet exec:exec -Dexec.mainClass="${WWDEMO}" \ No newline at end of file diff --git a/run-demo.bat b/run-demo.bat index cbc67c0b8d..baf143b016 100755 --- a/run-demo.bat +++ b/run-demo.bat @@ -28,6 +28,13 @@ REM notices and licenses PDF found in code directory. REM Default to the ApplicationTemplate example if a class name is not provided IF "%1"=="" (SET WWDEMO=gov.nasa.worldwindx.examples.ApplicationTemplate) ELSE (SET WWDEMO=%*) -REM Run a WorldWind Demo +REM Run a WorldWind Demo via Maven. +REM +REM Maven resolves the full classpath (JOGL 2.6.0, GlueGen 2.6.0, GDAL, etc.) +REM from the project dependencies declared in pom.xml, so no manual classpath +REM management is required here. +REM +REM The --add-opens flags are declared in the exec-maven-plugin configuration +REM in pom.xml and are forwarded automatically to the forked JVM. @echo Running %WWDEMO% -java -Xmx1024m -Dsun.java2d.noddraw=true -classpath .\worldwind.jar;.\worldwindx.jar;.\gdal.jar;.\jogl-all.jar;.\gluegen-rt.jar %WWDEMO% +mvn --quiet exec:exec "-Dexec.mainClass=%WWDEMO%" diff --git a/src/com/zebraimaging/ZebraInputHandler.java b/src/com/zebraimaging/ZebraInputHandler.java index 10abc1936a..281cff8245 100644 --- a/src/com/zebraimaging/ZebraInputHandler.java +++ b/src/com/zebraimaging/ZebraInputHandler.java @@ -22,18 +22,16 @@ public class ZebraInputHandler extends AWTInputHandler final static TimerTask repaintContextsTask = new TimerTask() { + @Override public void run() { - Iterator itr = instances.iterator(); - while (itr.hasNext()) - { - ZebraInputHandler h = itr.next(); - if (h.NeedsRefresh() == true) - { - h.SetRefresh(false); - h.getWorldWindow().redraw(); - } - } + for (ZebraInputHandler h : instances) { + if (h.NeedsRefresh() == true) + { + h.SetRefresh(false); + h.getWorldWindow().redraw(); + } + } } }; @@ -77,6 +75,7 @@ private synchronized boolean NeedsRefresh() return refresh; } + @Override public void keyPressed(KeyEvent e) { boolean consumed = false; @@ -88,6 +87,7 @@ public void keyPressed(KeyEvent e) super.keyPressed(e); } + @Override public void keyReleased(KeyEvent e) { boolean consumed = false; @@ -99,6 +99,7 @@ public void keyReleased(KeyEvent e) super.keyReleased(e); } + @Override public void mouseClicked(MouseEvent e) { boolean consumed = false; @@ -110,6 +111,7 @@ public void mouseClicked(MouseEvent e) super.mouseClicked(e); } + @Override public void mousePressed(MouseEvent e) { boolean consumed = false; @@ -121,6 +123,7 @@ public void mousePressed(MouseEvent e) super.mousePressed(e); } + @Override public void mouseReleased(MouseEvent e) { boolean consumed = false; diff --git a/src/gov/nasa/worldwind/AbstractSceneController.java b/src/gov/nasa/worldwind/AbstractSceneController.java index 23e057b6a0..46b519da63 100644 --- a/src/gov/nasa/worldwind/AbstractSceneController.java +++ b/src/gov/nasa/worldwind/AbstractSceneController.java @@ -68,7 +68,7 @@ public abstract class AbstractSceneController extends WWObjectImpl implements Sc * #doResolveTopPick(gov.nasa.worldwind.render.DrawContext, java.awt.Rectangle)}. This map is used only when a pick * rectangle is specified. Initialized to a new HashMap. */ - protected Map pickableObjects = new HashMap(); + protected Map pickableObjects = new HashMap<>(); protected long frame = 0; protected long timebase = System.currentTimeMillis(); protected double framesPerSecond; @@ -87,7 +87,7 @@ public abstract class AbstractSceneController extends WWObjectImpl implements Sc protected boolean deepPick = false; protected GpuResourceCache gpuResourceCache; protected TextRendererCache textRendererCache = new TextRendererCache(); - protected Set perFrameStatisticsKeys = new HashSet(); + protected Set perFrameStatisticsKeys = new HashSet<>(); protected Collection perFrameStatistics = new ArrayList(); protected Collection renderingExceptions = new ArrayList(); protected ScreenCreditController screenCreditController; diff --git a/src/gov/nasa/worldwind/formats/geojson/GeoJSONDoc.java b/src/gov/nasa/worldwind/formats/geojson/GeoJSONDoc.java index 62cc433c22..13b532a8f2 100644 --- a/src/gov/nasa/worldwind/formats/geojson/GeoJSONDoc.java +++ b/src/gov/nasa/worldwind/formats/geojson/GeoJSONDoc.java @@ -28,7 +28,7 @@ package gov.nasa.worldwind.formats.geojson; import gov.nasa.worldwind.formats.json.*; -import org.codehaus.jackson.JsonParser; +import com.fasterxml.jackson.core.JsonParser; import java.io.IOException; diff --git a/src/gov/nasa/worldwind/formats/geojson/GeoJSONEventParserContext.java b/src/gov/nasa/worldwind/formats/geojson/GeoJSONEventParserContext.java index d15f507477..c366280b11 100644 --- a/src/gov/nasa/worldwind/formats/geojson/GeoJSONEventParserContext.java +++ b/src/gov/nasa/worldwind/formats/geojson/GeoJSONEventParserContext.java @@ -27,7 +27,7 @@ */ package gov.nasa.worldwind.formats.geojson; -import org.codehaus.jackson.JsonParser; +import com.fasterxml.jackson.core.JsonParser; import gov.nasa.worldwind.formats.json.*; import java.io.IOException; diff --git a/src/gov/nasa/worldwind/formats/json/BasicJSONEvent.java b/src/gov/nasa/worldwind/formats/json/BasicJSONEvent.java index 5ca60fddcf..7d9f773b31 100644 --- a/src/gov/nasa/worldwind/formats/json/BasicJSONEvent.java +++ b/src/gov/nasa/worldwind/formats/json/BasicJSONEvent.java @@ -28,7 +28,7 @@ package gov.nasa.worldwind.formats.json; import gov.nasa.worldwind.util.Logging; -import org.codehaus.jackson.*; +import com.fasterxml.jackson.core.*; import java.io.IOException; diff --git a/src/gov/nasa/worldwind/formats/json/BasicJSONEventParserContext.java b/src/gov/nasa/worldwind/formats/json/BasicJSONEventParserContext.java index fc577ff1d8..0cdd64f75b 100644 --- a/src/gov/nasa/worldwind/formats/json/BasicJSONEventParserContext.java +++ b/src/gov/nasa/worldwind/formats/json/BasicJSONEventParserContext.java @@ -28,7 +28,7 @@ package gov.nasa.worldwind.formats.json; import gov.nasa.worldwind.util.Logging; -import org.codehaus.jackson.*; +import com.fasterxml.jackson.core.*; import java.io.IOException; import java.util.*; @@ -132,11 +132,11 @@ protected JSONEvent createEvent(JsonToken token) throws IOException { if (token == JsonToken.VALUE_NUMBER_INT || token == JsonToken.VALUE_NUMBER_FLOAT) { - return new NumericValueJSONEvent(this.parser.getCurrentName(), this.parser.getDoubleValue()); + return new NumericValueJSONEvent(this.parser.currentName(), this.parser.getDoubleValue()); } else { - return new BasicJSONEvent(this.parser, token, this.parser.getCurrentName()); + return new BasicJSONEvent(this.parser, token, this.parser.currentName()); } } } diff --git a/src/gov/nasa/worldwind/formats/json/JSONDoc.java b/src/gov/nasa/worldwind/formats/json/JSONDoc.java index ea01056b56..1d2159adca 100644 --- a/src/gov/nasa/worldwind/formats/json/JSONDoc.java +++ b/src/gov/nasa/worldwind/formats/json/JSONDoc.java @@ -29,7 +29,7 @@ import gov.nasa.worldwind.exception.WWRuntimeException; import gov.nasa.worldwind.util.*; -import org.codehaus.jackson.*; +import com.fasterxml.jackson.core.*; import java.io.*; @@ -68,7 +68,7 @@ public JSONDoc(Object source) protected void initialize(Object source) throws Exception { JsonFactory factory = new JsonFactory(); - this.jsonParser = factory.createJsonParser(WWIO.openStream(source)); + this.jsonParser = factory.createParser(WWIO.openStream(source)); } public Object getRootObject() diff --git a/src/gov/nasa/worldwind/util/BrowserOpener.java b/src/gov/nasa/worldwind/util/BrowserOpener.java index 0363e8c77f..75ccd13b56 100644 --- a/src/gov/nasa/worldwind/util/BrowserOpener.java +++ b/src/gov/nasa/worldwind/util/BrowserOpener.java @@ -27,9 +27,7 @@ */ package gov.nasa.worldwind.util; -import gov.nasa.worldwind.Configuration; - -import java.lang.reflect.Method; +import java.awt.Desktop; import java.net.URL; /** @@ -49,44 +47,11 @@ public static void browse(URL url) throws Exception try { - String urlString = url.toString(); - if (Configuration.isMacOS()) - browseMacOS(urlString); - else if (Configuration.isWindowsOS()) - browseWindows(urlString); - else if (Configuration.isUnixOS() || Configuration.isLinuxOS()) - browseUnix(urlString); + Desktop.getDesktop().browse(url.toURI()); } catch (Exception e) { throw new Exception(String.format("Cannot browse URL %s", url), e); } } - - private static void browseMacOS(String urlString) throws Exception - { - Class fileManager = Class.forName("com.apple.eio.FileManager"); - Method openURL = fileManager.getDeclaredMethod("openURL", String.class); - openURL.invoke(null, urlString); - } - - private static void browseWindows(String urlString) throws Exception - { - Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + urlString); - } - - private static void browseUnix(String urlString) throws Exception - { - String browser = null; - - String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape"}; - for (String curBrowser : browsers) - if (Runtime.getRuntime().exec(new String[] {"which", curBrowser}).waitFor() == 0) - browser = curBrowser; - - if (browser == null) - throw new Exception("Cannot find browser"); - - Runtime.getRuntime().exec(new String[] {browser, urlString}); - } } \ No newline at end of file diff --git a/src/gov/nasa/worldwind/util/gdal/GDALUtils.java b/src/gov/nasa/worldwind/util/gdal/GDALUtils.java index 53a5939957..0a9663d757 100644 --- a/src/gov/nasa/worldwind/util/gdal/GDALUtils.java +++ b/src/gov/nasa/worldwind/util/gdal/GDALUtils.java @@ -152,13 +152,8 @@ protected static void replaceLibraryLoader() { } protected static boolean is32bitArchitecture() { - String arch = System.getProperty("sun.arch.data.model"); - if (!WWUtil.isEmpty(arch)) { - return ("32".equals(arch)); - } - - // GNU JAVA does not return "sun.arch.data.model" - return "x86".equals(System.getProperty("os.arch")); + String arch = System.getProperty("os.arch"); + return arch != null && (arch.equals("x86") || arch.equals("i386") || arch.equals("i686")); } protected static boolean gdalPreLoadNativeLibrary(String folder, boolean allowLogErrors) { diff --git a/src/org/codehaus/jackson/Base64Variant.java b/src/org/codehaus/jackson/Base64Variant.java deleted file mode 100644 index 9fcb0b636d..0000000000 --- a/src/org/codehaus/jackson/Base64Variant.java +++ /dev/null @@ -1,362 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codehaus.jackson; - -import java.util.Arrays; - -/** - * Abstract base class used to define specific details of which - * variant of Base64 encoding/decoding is to be used. Although there is - * somewhat standard basic version (so-called "MIME Base64"), other variants - * exists, see Base64 Wikipedia entry for details. - * - * @author Tatu Saloranta - * - * @since 0.9.3 - */ -public final class Base64Variant -{ - /** - * Placeholder used by "no padding" variant, to be used when a character - * value is needed. - */ - final static char PADDING_CHAR_NONE = '\0'; - - /** - * Marker used to denote ascii characters that do not correspond - * to a 6-bit value (in this variant), and is not used as a padding - * character. - */ - public final static int BASE64_VALUE_INVALID = -1; - - /** - * Marker used to denote ascii character (in decoding table) that - * is the padding character using this variant (if any). - */ - public final static int BASE64_VALUE_PADDING = -2; - - /* - //////////////////////////////////////////////////// - // Encoding/decoding tables - //////////////////////////////////////////////////// - */ - - /** - * Decoding table used for base 64 decoding. - */ - private final int[] _asciiToBase64 = new int[128]; - - /** - * Encoding table used for base 64 decoding when output is done - * as characters. - */ - private final char[] _base64ToAsciiC = new char[64]; - - /** - * Alternative encoding table used for base 64 decoding when output is done - * as ascii bytes. - */ - private final byte[] _base64ToAsciiB = new byte[64]; - - /* - //////////////////////////////////////////////////// - // Other configuration - //////////////////////////////////////////////////// - */ - - /** - * Symbolic name of variant; used for diagnostics/debugging. - */ - final String _name; - - /** - * Whether this variant uses padding or not. - */ - final boolean _usesPadding; - - /** - * Characted used for padding, if any ({@link #PADDING_CHAR_NONE} if not). - */ - final char _paddingChar; - - /** - * Maximum number of encoded base64 characters to output during encoding - * before adding a linefeed, if line length is to be limited - * ({@link java.lang.Integer#MAX_VALUE} if not limited). - *

- * Note: for some output modes (when writing attributes) linefeeds may - * need to be avoided, and this value ignored. - */ - final int _maxLineLength; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - public Base64Variant(String name, String base64Alphabet, boolean usesPadding, char paddingChar, int maxLineLength) - { - _name = name; - _usesPadding = usesPadding; - _paddingChar = paddingChar; - _maxLineLength = maxLineLength; - - // Ok and then we need to create codec tables. - - // First the main encoding table: - int alphaLen = base64Alphabet.length(); - if (alphaLen != 64) { - throw new IllegalArgumentException("Base64Alphabet length must be exactly 64 (was "+alphaLen+")"); - } - - // And then secondary encoding table and decoding table: - base64Alphabet.getChars(0, alphaLen, _base64ToAsciiC, 0); - Arrays.fill(_asciiToBase64, BASE64_VALUE_INVALID); - for (int i = 0; i < alphaLen; ++i) { - char alpha = _base64ToAsciiC[i]; - _base64ToAsciiB[i] = (byte) alpha; - _asciiToBase64[alpha] = i; - } - - // Plus if we use padding, add that in too - if (usesPadding) { - _asciiToBase64[(int) paddingChar] = BASE64_VALUE_PADDING; - } - } - - /** - * "Copy constructor" that can be used when the base alphabet is identical - * to one used by another variant except for the maximum line length - * (and obviously, name). - * @param base Undocumented. - * @param name Undocumented. - * @param maxLineLength Undocumented. - */ - public Base64Variant(Base64Variant base, String name, int maxLineLength) - { - this(base, name, base._usesPadding, base._paddingChar, maxLineLength); - } - - /** - * "Copy constructor" that can be used when the base alphabet is identical - * to one used by another variant, but other details (padding, maximum - * line length) differ - * @param base Undocumented. - * @param name Undocumented. - * @param usesPadding Undocumented. - * @param paddingChar Undocumented. - * @param maxLineLength Undocumented. - */ - public Base64Variant(Base64Variant base, String name, boolean usesPadding, char paddingChar, int maxLineLength) - { - _name = name; - byte[] srcB = base._base64ToAsciiB; - System.arraycopy(srcB, 0, this._base64ToAsciiB, 0, srcB.length); - char[] srcC = base._base64ToAsciiC; - System.arraycopy(srcC, 0, this._base64ToAsciiC, 0, srcC.length); - int[] srcV = base._asciiToBase64; - System.arraycopy(srcV, 0, this._asciiToBase64, 0, srcV.length); - - _usesPadding = usesPadding; - _paddingChar = paddingChar; - _maxLineLength = maxLineLength; - } - - /* - //////////////////////////////////////////////////// - // Public accessors - //////////////////////////////////////////////////// - */ - - public String getName() { return _name; } - - public boolean usesPadding() { return _usesPadding; } - public boolean usesPaddingChar(char c) { return c == _paddingChar; } - public boolean usesPaddingChar(int ch) { return ch == (int) _paddingChar; } - public char getPaddingChar() { return _paddingChar; } - public byte getPaddingByte() { return (byte)_paddingChar; } - - public int getMaxLineLength() { return _maxLineLength; } - - /* - //////////////////////////////////////////////////// - // Decoding support - //////////////////////////////////////////////////// - */ - - /** - * @param c Undocumented. - * @return 6-bit decoded value, if valid character; - */ - public int decodeBase64Char(char c) - { - int ch = (int) c; - return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID; - } - - public int decodeBase64Char(int ch) - { - return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID; - } - - public int decodeBase64Byte(byte b) - { - int ch = (int) b; - return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID; - } - - /* - //////////////////////////////////////////////////// - // Encoding support - //////////////////////////////////////////////////// - */ - - public char encodeBase64BitsAsChar(int value) - { - /* Let's assume caller has done necessary checks; this - * method must be fast and inlinable - */ - return _base64ToAsciiC[value]; - } - - /** - * Method that encodes given right-aligned (LSB) 24-bit value - * into 4 base64 characters, stored in given result buffer. - * @param b24 Undocumented. - * @param buffer Undocumented. - * @param ptr Undocumented. - * @return Undocumented. - */ - public int encodeBase64Chunk(int b24, char[] buffer, int ptr) - { - buffer[ptr++] = _base64ToAsciiC[(b24 >> 18) & 0x3F]; - buffer[ptr++] = _base64ToAsciiC[(b24 >> 12) & 0x3F]; - buffer[ptr++] = _base64ToAsciiC[(b24 >> 6) & 0x3F]; - buffer[ptr++] = _base64ToAsciiC[b24 & 0x3F]; - return ptr; - } - - public void encodeBase64Chunk(StringBuilder sb, int b24) - { - sb.append(_base64ToAsciiC[(b24 >> 18) & 0x3F]); - sb.append(_base64ToAsciiC[(b24 >> 12) & 0x3F]); - sb.append(_base64ToAsciiC[(b24 >> 6) & 0x3F]); - sb.append(_base64ToAsciiC[b24 & 0x3F]); - } - - /** - * Method that outputs partial chunk (which only encodes one - * or two bytes of data).Data given is still aligned same as if - it as full data; that is, missing data is at the "right end" - (LSB) of int. - * - * @param bits Undocumented. - * @param outputBytes Number of encoded bytes included (either 1 or 2) - * @param buffer Undocumented. - * @param outPtr Undocumented. - * @return Undocumented. - */ - public int encodeBase64Partial(int bits, int outputBytes, char[] buffer, int outPtr) - { - buffer[outPtr++] = _base64ToAsciiC[(bits >> 18) & 0x3F]; - buffer[outPtr++] = _base64ToAsciiC[(bits >> 12) & 0x3F]; - if (_usesPadding) { - buffer[outPtr++] = (outputBytes == 2) ? - _base64ToAsciiC[(bits >> 6) & 0x3F] : _paddingChar; - buffer[outPtr++] = _paddingChar; - } else { - if (outputBytes == 2) { - buffer[outPtr++] = _base64ToAsciiC[(bits >> 6) & 0x3F]; - } - } - return outPtr; - } - - public void encodeBase64Partial(StringBuilder sb, int bits, int outputBytes) - { - sb.append(_base64ToAsciiC[(bits >> 18) & 0x3F]); - sb.append(_base64ToAsciiC[(bits >> 12) & 0x3F]); - if (_usesPadding) { - sb.append((outputBytes == 2) ? - _base64ToAsciiC[(bits >> 6) & 0x3F] : _paddingChar); - sb.append(_paddingChar); - } else { - if (outputBytes == 2) { - sb.append(_base64ToAsciiC[(bits >> 6) & 0x3F]); - } - } - } - - public byte encodeBase64BitsAsByte(int value) - { - // As with above, assuming it is 6-bit value - return _base64ToAsciiB[value]; - } - - /** - * Method that encodes given right-aligned (LSB) 24-bit value - * into 4 base64 bytes (ascii), stored in given result buffer. - * @param b24 Undocumented. - * @param buffer Undocumented. - * @param ptr Undocumented. - * @return Undocumented. - */ - public int encodeBase64Chunk(int b24, byte[] buffer, int ptr) - { - buffer[ptr++] = _base64ToAsciiB[(b24 >> 18) & 0x3F]; - buffer[ptr++] = _base64ToAsciiB[(b24 >> 12) & 0x3F]; - buffer[ptr++] = _base64ToAsciiB[(b24 >> 6) & 0x3F]; - buffer[ptr++] = _base64ToAsciiB[b24 & 0x3F]; - return ptr; - } - - /** - * Method that outputs partial chunk (which only encodes one or two bytes of data).Data given is still aligned same - * as if it as full data; that is, missing data is at the "right end" (LSB) of int. - * - * @param bits Undocumented. - * @param outputBytes Number of encoded bytes included (either 1 or 2) - * @param buffer Undocumented. - * @param outPtr Undocumented. - * @return Undocumented. - */ - public int encodeBase64Partial(int bits, int outputBytes, byte[] buffer, int outPtr) - { - buffer[outPtr++] = _base64ToAsciiB[(bits >> 18) & 0x3F]; - buffer[outPtr++] = _base64ToAsciiB[(bits >> 12) & 0x3F]; - if (_usesPadding) { - byte pb = (byte) _paddingChar; - buffer[outPtr++] = (outputBytes == 2) ? - _base64ToAsciiB[(bits >> 6) & 0x3F] : pb; - buffer[outPtr++] = pb; - } else { - if (outputBytes == 2) { - buffer[outPtr++] = _base64ToAsciiB[(bits >> 6) & 0x3F]; - } - } - return outPtr; - } - - /* - //////////////////////////////////////////////////// - // other methods - //////////////////////////////////////////////////// - */ - - // @Override - public String toString() { return _name; } -} - diff --git a/src/org/codehaus/jackson/Base64Variants.java b/src/org/codehaus/jackson/Base64Variants.java deleted file mode 100644 index 0a6b2bcb12..0000000000 --- a/src/org/codehaus/jackson/Base64Variants.java +++ /dev/null @@ -1,90 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codehaus.jackson; - -/** - * Container for commonly used Base64 variants. - * - * @author Tatu Saloranta - */ -public final class Base64Variants -{ - final static String STD_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /** - * This variant is what most people would think of "the standard" - * Base64 encoding. - *

- * See wikipedia Base64 entry for details. - *

- * Note that although this can be thought of as the standard variant, - * it is not the default for Jackson: no-linefeeds alternative - * is because of JSON requirement of escaping all linefeeds. - */ - public final static Base64Variant MIME; - static { - MIME = new Base64Variant("MIME", STD_BASE64_ALPHABET, true, '=', 76); - } - - /** - * Slightly non-standard modification of {@link #MIME} which does not - * use linefeeds (max line length set to infinite). Useful when linefeeds - * wouldn't work well (possibly in attributes), or for minor space savings - * (save 1 linefeed per 76 data chars, ie. ~1.4% savings). - */ - public final static Base64Variant MIME_NO_LINEFEEDS; - static { - MIME_NO_LINEFEEDS = new Base64Variant(MIME, "MIME-NO-LINEFEEDS", Integer.MAX_VALUE); - } - - /** - * This variant is the one that predates {@link #MIME}: it is otherwise - * identical, except that it mandates shorter line length. - */ - public final static Base64Variant PEM = new Base64Variant(MIME, "PEM", true, '=', 64); - - /** - * This non-standard variant is usually used when encoded data needs to be - * passed via URLs (such as part of GET request). It differs from the - * base {@link #MIME} variant in multiple ways. - * First, no padding is used: this also means that it generally can not - * be written in multiple separate but adjacent chunks (which would not - * be the usual use case in any case). Also, no linefeeds are used (max - * line length set to infinite). And finally, two characters (plus and - * slash) that would need quoting in URLs are replaced with more - * optimal alternatives (hyphen and underscore, respectively). - */ - public final static Base64Variant MODIFIED_FOR_URL; - static { - StringBuffer sb = new StringBuffer(STD_BASE64_ALPHABET); - // Replace plus with hyphen, slash with underscore (and no padding) - sb.setCharAt(sb.indexOf("+"), '-'); - sb.setCharAt(sb.indexOf("/"), '_'); - /* And finally, let's not split lines either, wouldn't work too - * well with URLs - */ - MODIFIED_FOR_URL = new Base64Variant("MODIFIED-FOR-URL", sb.toString(), false, Base64Variant.PADDING_CHAR_NONE, Integer.MAX_VALUE); - } - - /** - * Method used to get the default variant ("MIME_NO_LINEFEEDS") for cases - * where caller does not explicitly specify the variant.We will prefer no-linefeed version because linefeeds in JSON values - must be escaped, making linefeed-containing variants sub-optimal. - * @return Undocumented. - */ - public static Base64Variant getDefaultVariant() { - return MIME_NO_LINEFEEDS; - } -} diff --git a/src/org/codehaus/jackson/JsonEncoding.java b/src/org/codehaus/jackson/JsonEncoding.java deleted file mode 100644 index 46495ad82c..0000000000 --- a/src/org/codehaus/jackson/JsonEncoding.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.codehaus.jackson; - -/** - * Enumeration that defines legal encodings that can be used - * for JSON content, based on list of allowed encodings from - * JSON specification. - *

- * Note: if application want to explicitly disregard Encoding - * limitations (to read in JSON encoded using an encoding not - * listed as allowed), they can use {@link java.io.Reader} / - * {@link java.io.Writer} instances as input - * source (or output target). - */ -public enum JsonEncoding { - UTF8("UTF-8", false), // N/A for big-endian, really - UTF16_BE("UTF-16BE", true), - UTF16_LE("UTF-16LE", false), - UTF32_BE("UTF-32BE", true), - UTF32_LE("UTF-32LE", false) - ; - - final String mJavaName; - - final boolean mBigEndian; - - JsonEncoding(String javaName, boolean bigEndian) - { - mJavaName = javaName; - mBigEndian = bigEndian; - } - - /** - * Method for accessing encoding name that JDK will support. - * - * @return Matching encoding name that JDK will support. - */ - public String getJavaName() { return mJavaName; } - - /** - * Whether encoding is big-endian (if encoding supports such - * notion). If no such distinction is made (as is the case for - * {@link #UTF8}), return value is undefined. - * - * @return True for big-endian encodings; false for little-endian - * (or if not applicable) - */ - public boolean isBigEndian() { return mBigEndian; } -} diff --git a/src/org/codehaus/jackson/JsonFactory.java b/src/org/codehaus/jackson/JsonFactory.java deleted file mode 100644 index 125c63ca37..0000000000 --- a/src/org/codehaus/jackson/JsonFactory.java +++ /dev/null @@ -1,642 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codehaus.jackson; - -import java.io.*; -import java.lang.ref.SoftReference; -import java.net.URL; - -import org.codehaus.jackson.io.*; -import org.codehaus.jackson.impl.ByteSourceBootstrapper; -import org.codehaus.jackson.impl.ReaderBasedParser; -import org.codehaus.jackson.impl.WriterBasedGenerator; -import org.codehaus.jackson.sym.BytesToNameCanonicalizer; -import org.codehaus.jackson.sym.CharsToNameCanonicalizer; -import org.codehaus.jackson.util.BufferRecycler; - -/** - * The main factory class of Jackson package, used to configure and - * construct reader (aka parser, {@link JsonParser}) - * and writer (aka generator, {@link JsonGenerator}) - * instances. - *

- * Factory instances are thread-safe and reusable after configuration - * (if any). Typically applications and services use only a single - * globally shared factory instance, unless they need differently - * configured factories. Factory reuse is important if efficiency matters; - * most recycling of expensive construct is done on per-factory basis. - *

- * Creation of a factory instance is a light-weight operation, - * and since there is no need for pluggable alternative implementations - * (as there is no "standard" json processor API to implement), - * the default constructor is used for constructing factory - * instances. - * - * @author Tatu Saloranta - */ -public class JsonFactory -{ - /** - * Bitfield (set of flags) of all parser features that are enabled - * by default. - */ - final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults(); - - /** - * Bitfield (set of flags) of all generator features that are enabled - * by default. - */ - final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults(); - - /* - /****************************************************** - /* Buffer, symbol table management - /****************************************************** - */ - - /** - * This ThreadLocal contains a {@link SoftRerefence} - * to a {@link BufferRecycler} used to provide a low-cost - * buffer recycling between reader and writer instances. - */ - final static ThreadLocal> _recyclerRef = new ThreadLocal>(); - - /** - * Each factory comes equipped with a shared root symbol table. - * It should not be linked back to the original blueprint, to - * avoid contents from leaking between factories. - */ - protected CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot(); - - /** - * Alternative to the basic symbol table, some stream-based - * parsers use different name canonicalization method. - *

- * TODO: should clean up this; looks messy having 2 alternatives - * with not very clear differences. - */ - protected BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot(); - - /* - /****************************************************** - /* Configuration - /****************************************************** - */ - - /** - * Object that implements conversion functionality between - * Java objects and Json content. For base JsonFactory implementation - * usually not set by default, but can be explicitly set. - * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory} - * usually provide an implementation. - */ - protected ObjectCodec _objectCodec; - - protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS; - - protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS; - - /** - * Default constructor used to create factory instances. - * Creation of a factory instance is a light-weight operation, - * but it is still a good idea to reuse limited number of - * factory instances (and quite often just a single instance): - * factories are used as context for storing some reused - * processing objects (such as symbol tables parsers use) - * and this reuse only works within context of a single - * factory instance. - */ - public JsonFactory() { this(null); } - - public JsonFactory(ObjectCodec oc) { _objectCodec = oc; } - - /* - /****************************************************** - /* Configuration, parser settings - /****************************************************** - */ - - /** - * Method for enabling or disabling specified parser feature - * (check {@link JsonParser.Feature} for list of features) - * - * @param f Undocumented. - * @param state Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public final JsonFactory configure(JsonParser.Feature f, boolean state) - { - if (state) { - enable(f); - } else { - disable(f); - } - return this; - } - - /** - * Method for enabling specified parser feature - * (check {@link JsonParser.Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonFactory enable(JsonParser.Feature f) { - _parserFeatures |= f.getMask(); - return this; - } - - /** - * Method for disabling specified parser features - * (check {@link JsonParser.Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonFactory disable(JsonParser.Feature f) { - _parserFeatures &= ~f.getMask(); - return this; - } - - /** - * Checked whether specified parser feature is enabled. - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public final boolean isEnabled(JsonParser.Feature f) { - return (_parserFeatures & f.getMask()) != 0; - } - - // // // Older deprecated (as of 1.2) methods - - /** - * @param f Undocumented. - * @deprecated Use {@link #enable(JsonParser.Feature)} instead - */ - @Deprecated - public final void enableParserFeature(JsonParser.Feature f) { - enable(f); - } - - /** - * @param f Undocumented. - * @deprecated Use {@link #disable(JsonParser.Feature)} instead - */ - @Deprecated - public final void disableParserFeature(JsonParser.Feature f) { - disable(f); - } - - /** - * @param f Undocumented. - * @param state Undocumented. - * @deprecated Use {@link #configure(JsonParser.Feature, boolean)} instead - */ - @Deprecated - public final void setParserFeature(JsonParser.Feature f, boolean state) { - configure(f, state); - } - - /** - * @param f Undocumented. - * @return Undocumented. - * @deprecated Use {@link #isEnabled(JsonParser.Feature)} instead - */ - @Deprecated - public final boolean isParserFeatureEnabled(JsonParser.Feature f) { - return (_parserFeatures & f.getMask()) != 0; - } - - /* - ////////////////////////////////////////////////////// - // Configuration, generator settings - ////////////////////////////////////////////////////// - */ - - /** - * Method for enabling or disabling specified generator feature - * (check {@link JsonGenerator.Feature} for list of features) - * - * @param f Undocumented. - * @param state Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public final JsonFactory configure(JsonGenerator.Feature f, boolean state) { - if (state) { - enable(f); - } else { - disable(f); - } - return this; - } - - - /** - * Method for enabling specified generator features - * (check {@link JsonGenerator.Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonFactory enable(JsonGenerator.Feature f) { - _generatorFeatures |= f.getMask(); - return this; - } - - /** - * Method for disabling specified generator feature - * (check {@link JsonGenerator.Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonFactory disable(JsonGenerator.Feature f) { - _generatorFeatures &= ~f.getMask(); - return this; - } - - /** - * Checked whether specified generator feature is enabled. - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public final boolean isEnabled(JsonGenerator.Feature f) { - return (_generatorFeatures & f.getMask()) != 0; - } - - // // // Older deprecated (as of 1.2) methods - - /** - * @param f Undocumented. - * @deprecated Use {@link #enable(JsonGenerator.Feature)} instead - */ - @Deprecated - public final void enableGeneratorFeature(JsonGenerator.Feature f) { - enable(f); - } - - /** - * @param f Undocumented. - * @deprecated Use {@link #disable(JsonGenerator.Feature)} instead - */ - @Deprecated - public final void disableGeneratorFeature(JsonGenerator.Feature f) { - disable(f); - } - - /** - * @param f Undocumented. - * @param state Undocumented. - * @deprecated Use {@link #configure(JsonGenerator.Feature, boolean)} instead - */ - @Deprecated - public final void setGeneratorFeature(JsonGenerator.Feature f, boolean state) { - configure(f, state); - } - - /** - * @param f Undocumented. - * @return Undocumented. - * @deprecated Use {@link #isEnabled(JsonGenerator.Feature)} instead - */ - @Deprecated - public final boolean isGeneratorFeatureEnabled(JsonGenerator.Feature f) { - return isEnabled(f); - } - - /* - ////////////////////////////////////////////////////// - // Configuration, other - ////////////////////////////////////////////////////// - */ - - public JsonFactory setCodec(ObjectCodec oc) { - _objectCodec = oc; - return this; - } - - public ObjectCodec getCodec() { return _objectCodec; } - - /* - ////////////////////////////////////////////////////// - // Reader factories - ////////////////////////////////////////////////////// - */ - - /** - * Method for constructing json parser instance to parse - * contents of specified file.Encoding is auto-detected - from contents according to json specification recommended - mechanism.

- * Underlying input stream (needed for reading contents) - * will be owned (and managed, i.e. closed as need be) by - * the parser, since caller has no access to it. - * - * @param f File that contains JSON content to parse - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public JsonParser createJsonParser(File f) - throws IOException, JsonParseException - { - return _createJsonParser(new FileInputStream(f), _createContext(f, true)); - } - - /** - * Method for constructing json parser instance to parse contents of resource reference by given URL.Encoding is - * auto-detected from contents according to json specification recommended mechanism.

- * Underlying input stream (needed for reading contents) will be owned (and managed, i.e. closed as need be) - * by the parser, since caller has no access to it. - * - * @param url URL pointing to resource that contains JSON content to parse - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public JsonParser createJsonParser(URL url) - throws IOException, JsonParseException - { - return _createJsonParser(_optimizedStreamFromURL(url), _createContext(url, true)); - } - - /** - * Method for constructing json parser instance to parse - * the contents accessed via specified input stream. - *

- * The input stream will not be owned by - * the parser, it will still be managed (i.e. closed if - * end-of-stream is reacher, or parser close method called) - * if (and only if) {@link org.codehaus.jackson.JsonParser.Feature#AUTO_CLOSE_SOURCE} - * is enabled. - *

- * Note: no encoding argument is taken since it can always be - * auto-detected as suggested by Json RFC. - * - * @param in InputStream to use for reading JSON content to parse - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public JsonParser createJsonParser(InputStream in) - throws IOException, JsonParseException - { - return _createJsonParser(in, _createContext(in, false)); - } - - /** - * Method for constructing json parser instance to parse - * the contents accessed via specified Reader. -

- * The read stream will not be owned by - * the parser, it will still be managed (i.e. closed if - * end-of-stream is reacher, or parser close method called) - * if (and only if) {@link org.codehaus.jackson.JsonParser.Feature#AUTO_CLOSE_SOURCE} - * is enabled. - *

- * - * @param r Reader to use for reading JSON content to parse - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public JsonParser createJsonParser(Reader r) - throws IOException, JsonParseException - { - return _createJsonParser(r, _createContext(r, false)); - } - - public JsonParser createJsonParser(byte[] data) - throws IOException, JsonParseException - { - return _createJsonParser(data, 0, data.length, _createContext(data, true)); - } - - public JsonParser createJsonParser(byte[] data, int offset, int len) - throws IOException, JsonParseException - { - return _createJsonParser(data, offset, len, _createContext(data, true)); - } - - public JsonParser createJsonParser(String content) - throws IOException, JsonParseException - { - // true -> we own the Reader (and must close); not a big deal - Reader r = new StringReader(content); - return _createJsonParser(r, _createContext(r, true)); - } - - /* - ////////////////////////////////////////////////////// - // Generator factories - ////////////////////////////////////////////////////// - */ - - /** - * Method for constructing json generator for writing json content - * using specified output stream.Encoding to use must be specified, and needs to be one of available - types (as per JSON specification).

- * Underlying stream is NOT owned by the generator constructed, - * so that generator will NOT close the output stream when - * {@link JsonGenerator#close} is called (unless auto-closing - * feature, - * {@link org.codehaus.jackson.JsonGenerator.Feature#AUTO_CLOSE_TARGET} - * is enabled). - * Using application needs to close it explicitly if this is the case. - * - * @param out OutputStream to use for writing json content - * @param enc Character encoding to use - * @return Undocumented. - * @throws java.io.IOException Undocumented. - */ - public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc) - throws IOException - { - // false -> we won't manage the stream unless explicitly directed to - IOContext ctxt = _createContext(out, false); - ctxt.setEncoding(enc); - return _createJsonGenerator(_createWriter(out, enc, ctxt), ctxt); - } - - /** - * Method for constructing json generator for writing json content - * using specified Writer. - *

- * Underlying stream is NOT owned by the generator constructed, - * so that generator will NOT close the Reader when - * {@link JsonGenerator#close} is called (unless auto-closing - * feature, - * {@link org.codehaus.jackson.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled). - * Using application needs to close it explicitly. - * - * @param out Writer to use for writing json content - * @return Undocumented. - * @throws java.io.IOException Undocumented. - */ - public JsonGenerator createJsonGenerator(Writer out) - throws IOException - { - IOContext ctxt = _createContext(out, false); - return _createJsonGenerator(out, ctxt); - } - - /** - * Method for constructing json generator for writing json content - * to specified file, overwriting contents it might have (or creating - * it if such file does not yet exist).Encoding to use must be specified, and needs to be one of available - types (as per JSON specification).

- * Underlying stream is owned by the generator constructed, - * i.e. generator will handle closing of file when - * {@link JsonGenerator#close} is called. - * - * @param f File to write contents to - * @param enc Character encoding to use - * @return Undocumented. - * @throws java.io.IOException Undocumented. - */ - public JsonGenerator createJsonGenerator(File f, JsonEncoding enc) - throws IOException - { - OutputStream out = new FileOutputStream(f); - // true -> yes, we have to manage the stream since we created it - IOContext ctxt = _createContext(out, true); - ctxt.setEncoding(enc); - return _createJsonGenerator(_createWriter(out, enc, ctxt), ctxt); - } - - /* - /////////////////////////////////////////////////////////// - // Internal methods - /////////////////////////////////////////////////////////// - */ - - /** - * Overridable construction method that actually instantiates desired generator. - * @param srcRef Undocumented. - * @param resourceManaged Undocumented. - * @return Undocumented. - */ - protected IOContext _createContext(Object srcRef, boolean resourceManaged) - { - return new IOContext(_getBufferRecycler(), srcRef, resourceManaged); - } - - /** - * Overridable construction method that actually instantiates desired parser. - * @param in Undocumented. - * @param ctxt Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected JsonParser _createJsonParser(InputStream in, IOContext ctxt) - throws IOException, JsonParseException - { - return new ByteSourceBootstrapper(ctxt, in).constructParser(_parserFeatures, _objectCodec, _rootByteSymbols, _rootCharSymbols); - } - - protected JsonParser _createJsonParser(Reader r, IOContext ctxt) - throws IOException, JsonParseException - { - return new ReaderBasedParser(ctxt, _parserFeatures, r, _objectCodec, - _rootCharSymbols.makeChild(isEnabled(JsonParser.Feature.CANONICALIZE_FIELD_NAMES), - isEnabled(JsonParser.Feature.INTERN_FIELD_NAMES))); - } - - protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt) - throws IOException, JsonParseException - { - // true -> managed (doesn't really matter; we have no stream!) - return new ByteSourceBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures, _objectCodec, _rootByteSymbols, _rootCharSymbols); - } - - /** - * Overridable construction method that actually instantiates desired generator - * @param out Undocumented. - * @param ctxt Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - */ - protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt) - throws IOException - { - return new WriterBasedGenerator(ctxt, _generatorFeatures, _objectCodec, out); - } - - /** - * Method used by factory to create buffer recycler instances - * for parsers and generators. - *

- * Note: only public to give access for ObjectMapper - * @return Undocumented. - */ - public BufferRecycler _getBufferRecycler() - { - SoftReference ref = _recyclerRef.get(); - BufferRecycler br = (ref == null) ? null : ref.get(); - - if (br == null) { - br = new BufferRecycler(); - if (ref == null) { - _recyclerRef.set(new SoftReference(br)); - } - } - return br; - } - - /** - * Helper methods used for constructing an optimal stream for - * parsers to use, when input is to be read from an URL.This helps when reading file content via URL. - * @param url Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - */ - protected InputStream _optimizedStreamFromURL(URL url) - throws IOException - { - if ("file".equals(url.getProtocol())) { - /* Can not do this if the path refers - * to a network drive on windows. This fixes the problem; - * might not be needed on all platforms (NFS?), but should not - * matter a lot: performance penalty of extra wrapping is more - * relevant when accessing local file system. - */ - String host = url.getHost(); - if (host == null || host.length() == 0) { - return new FileInputStream(url.getPath()); - } - } - return url.openStream(); - } - - protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException - { - if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8 - return new UTF8Writer(ctxt, out); - } - // not optimal, but should do unless we really care about UTF-16/32 encoding speed - return new OutputStreamWriter(out, enc.getJavaName()); - } -} diff --git a/src/org/codehaus/jackson/JsonGenerationException.java b/src/org/codehaus/jackson/JsonGenerationException.java deleted file mode 100644 index 07499b3203..0000000000 --- a/src/org/codehaus/jackson/JsonGenerationException.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.codehaus.jackson; - -/** - * Exception type for exceptions during JSON writing, such as trying - * to output content in wrong context (non-matching end-array or end-object, - * for example). - */ -public class JsonGenerationException - extends JsonProcessingException -{ - final static long serialVersionUID = 123; // Stupid eclipse... - - public JsonGenerationException(Throwable rootCause) - { - super(rootCause); - } - - public JsonGenerationException(String msg) - { - super(msg, (JsonLocation)null); - } - - public JsonGenerationException(String msg, Throwable rootCause) - { - super(msg, (JsonLocation)null, rootCause); - } -} diff --git a/src/org/codehaus/jackson/JsonGenerator.java b/src/org/codehaus/jackson/JsonGenerator.java deleted file mode 100644 index 6821aa250b..0000000000 --- a/src/org/codehaus/jackson/JsonGenerator.java +++ /dev/null @@ -1,983 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.codehaus.jackson; - -import java.io.*; -import java.math.BigDecimal; -import java.math.BigInteger; - -/** - * Base class that defines public API for writing Json content. - * Instances are created using factory methods of - * a {@link JsonFactory} instance. - * - * @author Tatu Saloranta - */ -public abstract class JsonGenerator - implements Closeable -{ - /** - * Enumeration that defines all togglable features for generators. - */ - public enum Feature { - /** - * Feature that determines whether generator will automatically - * close underlying output target that is NOT owned by the - * generator. - * If disabled, calling application has to separately - * close the underlying {@link OutputStream} and {@link Writer} - * instances used to create the generator. If enabled, generator - * will handle closing, as long as generator itself gets closed: - * this happens when end-of-input is encountered, or generator - * is closed by a call to {@link JsonGenerator#close}. - *

- * Feature is enabled by default. - */ - AUTO_CLOSE_TARGET(true) - - /** - * Feature that determines what happens when the generator is - * closed while there are still unmatched - * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT} - * entries in output content. If enabled, such Array(s) and/or - * Object(s) are automatically closed; if disabled, nothing - * specific is done. - *

- * Feature is enabled by default. - */ - ,AUTO_CLOSE_JSON_CONTENT(true) - - /** - * Feature that determines whether Json Object field names are - * quoted using double-quotes, as specified by Json specification - * or not. Ability to disable quoting was added to support use - * cases where they are not usually expected, which most commonly - * occurs when used straight from javascript. - */ - ,QUOTE_FIELD_NAMES(true) - - /** - * Feature that determines whether "exceptional" (not real number) - * float/double values are outputted as quoted strings. - * The values checked are Double.Nan, - * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and - * associated Float values). - * If feature is disabled, these numbers are still output using - * associated literal values, resulting in non-conformant - * output - *

- * Feature is enabled by default. - */ - ,QUOTE_NON_NUMERIC_NUMBERS(true) - - /** - * Feature that forces all Java numbers to be written as JSON strings. - * Default state is 'false', meaning that Java numbers are to - * be serialized using basic numeric serialization (as JSON - * numbers, integral or floating point). If enabled, all such - * numeric values are instead written out as JSON Strings. - *

- * One use case is to avoid problems with Javascript limitations: - * since Javascript standard specifies that all number handling - * should be done using 64-bit IEEE 754 floating point values, - * result being that some 64-bit integer values can not be - * accurately represent (as mantissa is only 51 bit wide). - * - * @since 1.3 - */ - ,WRITE_NUMBERS_AS_STRINGS(false) - - ; - - final boolean _defaultState; - - final int _mask; - - /** - * Method that calculates bit set (flags) of all features that - * are enabled by default. - * @return Undocumented. - */ - public static int collectDefaults() - { - int flags = 0; - for (Feature f : values()) { - if (f.enabledByDefault()) { - flags |= f.getMask(); - } - } - return flags; - } - - private Feature(boolean defaultState) { - _defaultState = defaultState; - _mask = (1 << ordinal()); - } - - public boolean enabledByDefault() { return _defaultState; } - - public int getMask() { return _mask; } - }; - - // // // Configuration: - - /** - * Object that handles pretty-printing (usually additional - * white space to make results more human-readable) during - * output. If null, no pretty-printing is done. - */ - protected PrettyPrinter _cfgPrettyPrinter; - - protected JsonGenerator() { - } - - /* - //////////////////////////////////////////////////// - // Public API, configuration - //////////////////////////////////////////////////// - */ - - /** - * Method for enabling specified parser features: - * check {@link Feature} for list of available features. - * - * @param f Undocumented. - * @return Generator itself (this), to allow chaining - * - * @since 1.2 - */ - public abstract JsonGenerator enable(Feature f); - - /** - * Method for disabling specified features - * (check {@link Feature} for list of features) - * - * @param f Undocumented. - * @return Generator itself (this), to allow chaining - * - * @since 1.2 - */ - public abstract JsonGenerator disable(Feature f); - - /** - * Method for enabling or disabling specified feature: - * check {@link Feature} for list of available features. - * - * @param f Undocumented. - * @param state Undocumented. - * @return Generator itself (this), to allow chaining - * - * @since 1.2 - */ - public JsonGenerator configure(Feature f, boolean state) - { - if (state) { - enable(f); - } else { - disable(f); - } - return this; - } - - /** - * Method for checking whether given feature is enabled.Check {@link Feature} for list of available features. - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public abstract boolean isEnabled(Feature f); - - /** - * Method that can be called to set or reset the object to - * use for writing Java objects as JsonContent - * (using method {@link #writeObject}). - * - * @param oc Undocumented. - * @return Generator itself (this), to allow chaining - */ - public abstract JsonGenerator setCodec(ObjectCodec oc); - - /** - * Method for accessing the object used for writing Java - * object as Json content - * (using method {@link #writeObject}). - * @return Undocumented. - */ - public abstract ObjectCodec getCodec(); - - // // // Older deprecated versions - - /** - * @deprecated Use {@link #enable} instead - * @param f Undocumented. - */ - @Deprecated - public void enableFeature(Feature f) { enable(f); } - - /** - * @deprecated Use {@link #disable} instead - * @param f Undocumented. - */ - @Deprecated - public void disableFeature(Feature f) { disable(f); } - - /** - * @deprecated Use {@link #configure} instead - * @param f Undocumented. - * @param state Undocumented. - */ - @Deprecated - public void setFeature(Feature f, boolean state) { configure(f, state); } - - /** - * @param f Undocumented. - * @return Undocumented. - * @deprecated Use {@link #isEnabled} instead - */ - @Deprecated - public boolean isFeatureEnabled(Feature f) { return isEnabled(f); } - - - /* - //////////////////////////////////////////////////// - // Configuring generator - //////////////////////////////////////////////////// - */ - - /** - * Method for setting a custom pretty printer, which is usually - * used to add indentation for improved human readability.By default, generator does not do pretty printing.

- * To use the default pretty printer that comes with core - * Jackson distribution, call {@link #useDefaultPrettyPrinter} - * instead. - * - * @param pp Undocumented. - * @return Generator itself (this), to allow chaining - */ - public JsonGenerator setPrettyPrinter(PrettyPrinter pp) { - _cfgPrettyPrinter = pp; - return this; - } - - /** - * Convenience method for enabling pretty-printing using - * the default pretty printer - * ({@link org.codehaus.jackson.impl.DefaultPrettyPrinter}). - * - * @return Generator itself (this), to allow chaining - */ - public abstract JsonGenerator useDefaultPrettyPrinter(); - - /* - //////////////////////////////////////////////////// - // Public API, write methods, structural - //////////////////////////////////////////////////// - */ - - /** - * Method for writing starting marker of a Json Array value - * (character '['; plus possible white space decoration - * if pretty-printing is enabled). - *

- * Array values can be written in any context where values - * are allowed: meaning everywhere except for when - * a field name is expected. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeStartArray() - throws IOException, JsonGenerationException; - - /** - * Method for writing closing marker of a Json Array value - * (character ']'; plus possible white space decoration - * if pretty-printing is enabled). - *

- * Marker can be written if the innermost structured type - * is Array. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeEndArray() - throws IOException, JsonGenerationException; - - /** - * Method for writing starting marker of a Json Object value - * (character '{'; plus possible white space decoration - * if pretty-printing is enabled). - *

- * Object values can be written in any context where values - * are allowed: meaning everywhere except for when - * a field name is expected. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeStartObject() - throws IOException, JsonGenerationException; - - /** - * Method for writing closing marker of a Json Object value - * (character '}'; plus possible white space decoration - * if pretty-printing is enabled). - *

- * Marker can be written if the innermost structured type - * is Object, and the last written event was either a - * complete value, or START-OBJECT marker (see Json specification - * for more details). - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeEndObject() - throws IOException, JsonGenerationException; - - /** - * Method for writing a field name (json String surrounded by - * double quotes: syntactically identical to a json String value), - * possibly decorated by white space if pretty-printing is enabled. - *

- * Field names can only be written in Object context (check out - * Json specification for details), when field name is expected - * (field names alternate with values). - * @param name Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeFieldName(String name) - throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API, write methods, textual/binary - //////////////////////////////////////////////////// - */ - - /** - * Method for outputting a String value.Depending on context this means either array element, (object) field value - * or a stand alone String; but in all cases, String will be surrounded in double quotes, and contents will be - * properly escaped as required by Json specification. - * - * @param text Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeString(String text) - throws IOException, JsonGenerationException; - - public abstract void writeString(char[] text, int offset, int len) - throws IOException, JsonGenerationException; - - /** - * Fallback method which can be used to make generator copy - * input text verbatim with no modifications (including - * that no quoting is done and no separators are added even - * if context [array, object] would otherwise require such).If such separators are desired, use - {@link #writeRawValue(String)} instead. - * @param text Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeRaw(String text) - throws IOException, JsonGenerationException; - - public abstract void writeRaw(String text, int offset, int len) - throws IOException, JsonGenerationException; - - public abstract void writeRaw(char[] text, int offset, int len) - throws IOException, JsonGenerationException; - - public abstract void writeRaw(char c) - throws IOException, JsonGenerationException; - - /** - * Fallback method which can be used to make generator copy input text verbatim without any modifications, but - * assuming it must constitute a single legal Json value (number, string, boolean, null, Array or List).Assuming - * this, proper separators are added if and as needed (comma or colon), and generator state updated to reflect this. - * - * @param text Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeRawValue(String text) - throws IOException, JsonGenerationException; - - public abstract void writeRawValue(String text, int offset, int len) - throws IOException, JsonGenerationException; - - public abstract void writeRawValue(char[] text, int offset, int len) - throws IOException, JsonGenerationException; - - /** - * Method that will output given chunk of binary data as base64 - * encoded, as a complete String value (surrounded by double quotes).This method defaults

- * Note: because Json Strings can not contain unescaped linefeeds, - * if linefeeds are included (as per last argument), they must be - * escaped. This adds overhead for decoding without improving - * readability. - * Alternatively if linefeeds are not included, - * resulting String value may violate the requirement of base64 - * RFC which mandates line-length of 76 characters and use of - * linefeeds. However, all {@link JsonParser} implementations - * are required to accept such "long line base64"; as do - * typical production-level base64 decoders. - * - * @param b64variant Base64 variant to use: defines details such as - * whether padding is used (and if so, using which character); - * what is the maximum line length before adding linefeed, - * and also the underlying alphabet to use. - * @param data Undocumented. - * @param offset Undocumented. - * @param len Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeBinary(Base64Variant b64variant, - byte[] data, int offset, int len) - throws IOException, JsonGenerationException; - - /** - * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)}, - * but default to using the Jackson default Base64 variant - * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). - * @param data Undocumented. - * @param offset Undocumented. - * @param len Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeBinary(byte[] data, int offset, int len) - throws IOException, JsonGenerationException - { - writeBinary(Base64Variants.getDefaultVariant(), data, offset, len); - } - - /** - * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)}, but assumes default to using the Jackson default - * Base64 variant (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).Also assumes that whole byte array is to be - * output. - * - * @param data Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeBinary(byte[] data) - throws IOException, JsonGenerationException - { - writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length); - } - - /* - //////////////////////////////////////////////////// - // Public API, write methods, other value types - //////////////////////////////////////////////////// - */ - - /** - * Method for outputting given value as Json number.Can be called in any context where a value is expected - (Array value, Object field value, root-level value).Additional white space may be added around the value - if pretty-printing is enabled. - * @param v Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(int v) - throws IOException, JsonGenerationException; - - /** - * Method for outputting given value as Json number. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param v Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(long v) - throws IOException, JsonGenerationException; - - /** - * Method for outputting given value as Json number. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param v Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(BigInteger v) - throws IOException, JsonGenerationException; - - /** - * Method for outputting indicate Json numeric value. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param d Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(double d) - throws IOException, JsonGenerationException; - - /** - * Method for outputting indicate Json numeric value. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param f Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(float f) - throws IOException, JsonGenerationException; - - /** - * Method for outputting indicate Json numeric value. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param dec Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(BigDecimal dec) - throws IOException, JsonGenerationException; - - /** - * Write method that can be used for custom numeric types that can not be (easily?) converted to "standard" Java - * number types.Because numbers are not surrounded by double quotes, regular {@link #writeString} method can not be - * used; nor {@link #writeRaw} because that does not properly handle value separators needed in Array or Object - * contexts.

- * Note: because of lack of type safety, some generator implementations may not be able to implement this method. - * For example, if a binary json format is used, it may require type information for encoding; similarly for - * generator-wrappers around Java objects or Json nodes. If implementation does not implement this method, it needs - * to throw {@link UnsupportedOperationException}. - * - * @param encodedValue Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNumber(String encodedValue) - throws IOException, JsonGenerationException, - UnsupportedOperationException; - - /** - * Method for outputting literal Json boolean value (one of - * Strings 'true' and 'false'). - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @param state Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeBoolean(boolean state) - throws IOException, JsonGenerationException; - - /** - * Method for outputting literal Json null value. - * Can be called in any context where a value is expected - * (Array value, Object field value, root-level value). - * Additional white space may be added around the value - * if pretty-printing is enabled. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeNull() - throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API, write methods, serializing Java objects - //////////////////////////////////////////////////// - */ - - /** - * Method for writing given Java object (POJO) as Json. - * Exactly how the object gets written depends on object - * in question (ad on codec, its configuration); for most - * beans it will result in Json object, but for others Json - * array, or String or numeric value (and for nulls, Json - * null literal. - * NOTE: generator must have its object codec - * set to non-null value; for generators created by a mapping - * factory this is the case, for others not. - * @param pojo Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeObject(Object pojo) - throws IOException, JsonProcessingException; - - /** - * Method for writing given Json tree (expressed as a tree - * where given JsonNode is the root) using this generator. - * This will generally just call - * {@link #writeObject} with given node, but is added - * for convenience and to make code more explicit in cases - * where it deals specifically with trees. - * @param rootNode Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void writeTree(JsonNode rootNode) - throws IOException, JsonProcessingException; - - /* - //////////////////////////////////////////////////// - // Public API, convenience field write methods - //////////////////////////////////////////////////// - */ - - /** - * Convenience method for outputting a field entry ("member") - * that has a String value.Equivalent to:

-     *  writeFieldName(fieldName);
-     *  writeString(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeStringField(String fieldName, String value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeString(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has a boolean value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeBoolean(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeBooleanField(String fieldName, boolean value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeBoolean(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has Json literal value null.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNull();
-     *
- * @param fieldName Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNullField(String fieldName) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNull(); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has the specified numeric value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNumber(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNumberField(String fieldName, int value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNumber(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has the specified numeric value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNumber(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNumberField(String fieldName, long value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNumber(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has the specified numeric value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNumber(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNumberField(String fieldName, double value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNumber(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has the specified numeric value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNumber(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNumberField(String fieldName, float value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNumber(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has the specified numeric value.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeNumber(value);
-     *
- * @param fieldName Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeNumberField(String fieldName, BigDecimal value) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeNumber(value); - } - - /** - * Convenience method for outputting a field entry ("member") - * that contains specified data in base64-encoded form.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeBinary(value);
-     *
- * @param fieldName Undocumented. - * @param data Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeBinaryField(String fieldName, byte[] data) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeBinary(data); - } - - /** - * Convenience method for outputting a field entry ("member") - * (that will contain a Json Array value), and the START_ARRAY marker.Equivalent to:
-     *  writeFieldName(fieldName);
-     *  writeStartArray();
-     *
- *

- * Note: caller still has to take care to close the array - * (by calling {#link #writeEndArray}) after writing all values - * of the value Array. - * @param fieldName Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeArrayFieldStart(String fieldName) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeStartArray(); - } - - /** - * Convenience method for outputting a field entry ("member") - * (that will contain a Json Object value), and the START_OBJECT marker.Equivalent to:

-     *  writeFieldName(fieldName);
-     *  writeStartObject();
-     *
- *

- * Note: caller still has to take care to close the Object - * (by calling {#link #writeEndObject}) after writing all - * entries of the value Object. - * @param fieldName Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeObjectFieldStart(String fieldName) - throws IOException, JsonGenerationException - { - writeFieldName(fieldName); - writeStartObject(); - } - - /** - * Convenience method for outputting a field entry ("member") - * that has contents of specific Java object as its value.Equivalent to:

-     *  writeFieldName(fieldName);
-     *  writeObject(pojo);
-     *
- * @param fieldName Undocumented. - * @param pojo Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public final void writeObjectField(String fieldName, Object pojo) - throws IOException, JsonProcessingException - { - writeFieldName(fieldName); - writeObject(pojo); - } - - /* - //////////////////////////////////////////////////// - // Public API, copy-through methods - //////////////////////////////////////////////////// - */ - - /** - * Method for copying contents of the current event that - * the given parser instance points to.Note that the method will not copy any other events, - such as events contained within Json Array or Object structures.

- * Calling this method will not advance the given - * parser, although it may cause parser to internally process - * more data (if it lazy loads contents of value events, for example) - * @param jp Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void copyCurrentEvent(JsonParser jp) - throws IOException, JsonProcessingException; - - /** - * Method for copying contents of the current event - * and following events that it encloses - * the given parser instance points to. - *

- * So what constitutes enclosing? Here is the list of - * events that have associated enclosed events that will - * get copied: - *

    - *
  • {@link JsonToken#START_OBJECT}: - * all events up to and including matching (closing) - * {@link JsonToken#END_OBJECT} will be copied - *
  • - *
  • {@link JsonToken#START_ARRAY} - * all events up to and including matching (closing) - * {@link JsonToken#END_ARRAY} will be copied - *
  • - *
  • {@link JsonToken#FIELD_NAME} the logical value (which - * can consist of a single scalar value; or a sequence of related - * events for structured types (Json Arrays, Objects)) will - * be copied along with the name itself. So essentially the - * whole field entry (name and value) will be copied. - *
  • - *
- *

- * After calling this method, parser will point to the - * last event that was copied. This will either be - * the event parser already pointed to (if there were no - * enclosed events), or the last enclosed event copied. - * @param jp Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public abstract void copyCurrentStructure(JsonParser jp) - throws IOException, JsonProcessingException; - - /* - //////////////////////////////////////////////////// - // Public API, context access - //////////////////////////////////////////////////// - */ - - /** - * @return Context object that can give information about logical - * position within generated json content. - */ - public abstract JsonStreamContext getOutputContext(); - - /* - //////////////////////////////////////////////////// - // Public API, buffer handling - //////////////////////////////////////////////////// - */ - - /** - * Method called to flush any buffered content to the underlying - * target (output stream, writer), and to flush the target itself - * as well. - * @throws java.io.IOException Undocumented. - */ - public abstract void flush() - throws IOException; - - /** - * Method that can be called to determine whether this generator - * is closed or not.If it is closed, no more output can be done. - * @return Undocumented. - */ - public abstract boolean isClosed(); - - /* - //////////////////////////////////////////////////// - // Closeable implementation - //////////////////////////////////////////////////// - */ - - /** - * Method called to close this generator, so that no more content - * can be written. - *

- * Whether the underlying target (stream, writer) gets closed depends - * on whether this generator either manages the target (i.e. is the - * only one with access to the target -- case if caller passes a - * reference to the resource such as File, but not stream); or - * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled. - * If either of above is true, the target is also closed. Otherwise - * (not managing, feature not enabled), target is not closed. - */ - @Override - public abstract void close() - throws IOException; - -} diff --git a/src/org/codehaus/jackson/JsonLocation.java b/src/org/codehaus/jackson/JsonLocation.java deleted file mode 100644 index d8298f0a29..0000000000 --- a/src/org/codehaus/jackson/JsonLocation.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.codehaus.jackson; - -import org.codehaus.jackson.annotate.JsonCreator; -import org.codehaus.jackson.annotate.JsonProperty; - -/** - * Object that encapsulates Location information used for reporting - * parsing (or potentially generation) errors, as well as current location - * within input streams. - */ -public class JsonLocation - implements java.io.Serializable // as per [JACKSON-168] -{ - private static final long serialVersionUID = 1L; - - /** - * Shared immutable "N/A location" that can be returned to indicate - * that no location information is available - * - * @since 1.3 - */ - public final static JsonLocation NA = new JsonLocation("N/A", -1L, -1L, -1, -1); - - final long _totalBytes; - final long _totalChars; - - final int _lineNr; - final int _columnNr; - - /** - * Displayable description for input source: file path, url - */ - final Object _sourceRef; - - public JsonLocation(Object srcRef, long totalChars, int lineNr, int colNr) - { - /* Unfortunately, none of legal encodings are straight single-byte - * encodings. Could determine offset for UTF-16/UTF-32, but the - * most important one is UTF-8... - * so for now, we'll just not report any real byte count - */ - this(srcRef, -1L, totalChars, lineNr, colNr); - } - - @JsonCreator - public JsonLocation(@JsonProperty("sourceRef") Object sourceRef, - @JsonProperty("byteOffset") long totalBytes, - @JsonProperty("charOffset") long totalChars, - @JsonProperty("lineNr") int lineNr, - @JsonProperty("columnNr") int columnNr) - { - _sourceRef = sourceRef; - _totalBytes = totalBytes; - _totalChars = totalChars; - _lineNr = lineNr; - _columnNr = columnNr; - } - - /** - * Reference to the original resource being read, if one available.For example, when a parser has been constructed - * by passing a {@link java.io.File} instance, this method would return that File. Will return null if no such - * reference is available, for example when {@link java.io.InputStream} was used to construct the parser instance. - * - * @return Undocumented. - */ - public Object getSourceRef() { return _sourceRef; } - - /** - * @return Line number of the location (1-based) - */ - public int getLineNr() { return _lineNr; } - - /** - * @return Column number of the location (1-based) - */ - public int getColumnNr() { return _columnNr; } - - /** - * @return Character offset within underlying stream, reader or writer, - * if available; -1 if not. - */ - public long getCharOffset() { return _totalChars; } - - /** - * @return Byte offset within underlying stream, reader or writer, - * if available; -1 if not. - */ - public long getByteOffset() - { - return _totalBytes; - } - - @Override - public String toString() - { - StringBuilder sb = new StringBuilder(80); - sb.append("[Source: "); - if (_sourceRef == null) { - sb.append("UNKNOWN"); - } else { - sb.append(_sourceRef.toString()); - } - sb.append("; line: "); - sb.append(_lineNr); - sb.append(", column: "); - sb.append(_columnNr); - sb.append(']'); - return sb.toString(); - } - - @Override - public int hashCode() - { - int hash = (_sourceRef == null) ? 1 : _sourceRef.hashCode(); - hash ^= _lineNr; - hash += _columnNr; - hash ^= (int) _totalChars; - hash += (int) _totalBytes; - return hash; - } - - @Override - public boolean equals(Object other) - { - if (other == this) return true; - if (other == null) return false; - if (!(other instanceof JsonLocation)) return false; - JsonLocation otherLoc = (JsonLocation) other; - - if (_sourceRef == null) { - if (otherLoc._sourceRef != null) return false; - } else if (!_sourceRef.equals(otherLoc._sourceRef)) return false; - - return (_lineNr == otherLoc._lineNr) - && (_columnNr == otherLoc._columnNr) - && (_totalChars == otherLoc._totalChars) - && (getByteOffset() == otherLoc.getByteOffset()) - ; - } -} diff --git a/src/org/codehaus/jackson/JsonNode.java b/src/org/codehaus/jackson/JsonNode.java deleted file mode 100644 index b48bac39f1..0000000000 --- a/src/org/codehaus/jackson/JsonNode.java +++ /dev/null @@ -1,429 +0,0 @@ -package org.codehaus.jackson; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; - - -/** - * Base class for all JSON nodes, which form the basis of JSON - * Tree Model that Jackson implements. - * One way to think of these nodes is to considere them - * similar to DOM nodes in XML DOM trees. - *

- * As a general design rule, most accessors ("getters") are included - * in this base class, to allow for traversing structure without - * type casts. Most mutators, however, need to be accessed through - * specific sub-classes. This seems sensible because proper type - * information is generally available when building or modifying - * trees, but less often when reading a tree (newly built from - * parsed Json content). - */ -public abstract class JsonNode - implements Iterable -{ - final static List NO_NODES = Collections.emptyList(); - final static List NO_STRINGS = Collections.emptyList(); - - protected JsonNode() { } - - /* - //////////////////////////////////////////////////// - // Public API, type introspection - //////////////////////////////////////////////////// - */ - - // // First high-level division between values, containers and "missing" - - /** - * Method that returns true for all value nodes: ones that are not containers, and that do not represent "missing" - * nodes in the path.Such value nodes represent String, Number, Boolean and null values from JSON.

- * Note: one and only one of methods {@link #isValueNode}, - * {@link #isContainerNode} and {@link #isMissingNode} ever returns true for any given node. - * - * @return Undocumented. - */ - public boolean isValueNode() { return false; } - - /** - * Method that returns true for container nodes: Arrays and Objects. - *

- * Note: one and only one of methods {@link #isValueNode}, - * {@link #isContainerNode} and {@link #isMissingNode} ever - * returns true for any given node. - * @return Undocumented. - */ - public boolean isContainerNode() { return false; } - - /** - * Method that returns true for "virtual" nodes which represent - * missing entries constructed by path accessor methods when - * there is no actual node matching given criteria. - *

- * Note: one and only one of methods {@link #isValueNode}, - * {@link #isContainerNode} and {@link #isMissingNode} ever - * returns true for any given node. - * @return Undocumented. - */ - public boolean isMissingNode() { return false; } - - // // Then more specific type introspection - // // (along with defaults to be overridden) - - /** - * @return True if this node represents Json Array - */ - public boolean isArray() { return false; } - - /** - * @return True if this node represents Json Object - */ - public boolean isObject() { return false; } - - /** - * Method that can be used to check if the node is a wrapper - * for a POJO ("Plain Old Java Object" aka "bean". - * Returns true only for - * instances of org.codehaus.jackson.node.POJONode. - * - * @return True if this node wraps a POJO - */ - public boolean isPojo() { return false; } - - /** - * @return True if this node represents a numeric Json - * value - */ - public boolean isNumber() { return false; } - - /** - * @return True if this node represents an integral (integer) - * numeric Json value - */ - public boolean isIntegralNumber() { return false; } - - /** - * @return True if this node represents a non-integral - * numeric Json value - */ - public boolean isFloatingPointNumber() { return false; } - - /** - * @return True if this node represents an integral - * numeric Json value that withs in Java int value space - */ - public boolean isInt() { return false; } - - /** - * @return True if this node represents an integral - * numeric Json value that fits in Java long value space - * (but not int value space, i.e. {@link #isInt} returns false) - */ - public boolean isLong() { return false; } - - public boolean isDouble() { return false; } - public boolean isBigDecimal() { return false; } - public boolean isBigInteger() { return false; } - - public boolean isTextual() { return false; } - - /** - * Method that can be used to check if this node was created from - * Json boolean value (literals "true" and "false"). - * @return Undocumented. - */ - public boolean isBoolean() { return false; } - - /** - * Method that can be used to check if this node was created from - * Json liternal null value. - * @return Undocumented. - */ - public boolean isNull() { return false; } - - /** - * Method that can be used to check if this node represents - * binary data (Base64 encoded). Although this will be externally - * written as Json String value, {@link #isTextual} will - * return false if this method returns true. - * - * @return True if this node represents base64 encoded binary data - */ - public boolean isBinary() { return false; } - - /** - * Method that can be used for efficient type detection when using stream abstraction for traversing nodes.Will - * return the first {@link JsonToken} that equivalent stream event would produce (for most nodes there is just one - * token but for structured/container types multiple) - * - * @return Undocumented. - * @since 1.3 - */ - public abstract JsonToken asToken(); - - /** - * If this node is a numeric type (as per {@link #isNumber}), - * returns native type that node uses to store the numeric - * value. - * @return Undocumented. - */ - public abstract JsonParser.NumberType getNumberType(); - - /* - //////////////////////////////////////////////////// - // Public API, value access - //////////////////////////////////////////////////// - */ - - /** - * Method to use for accessing String values. - * Does NOT do any conversions for non-String value nodes; - * for non-String values (ones for which {@link #isTextual} returns - * false) null will be returned. - * For String values, null is never returned (but empty Strings may be) - * - * @return Textual value this node contains, iff it is a textual - * json node (comes from Json String value entry) - */ - public String getTextValue() { return null; } - - /** - * Method to use for accessing binary content of binary nodes (nodes - * for which {@link #isBinary} returns true); or for Text Nodes - * (ones for which {@link #getTextValue} returns non-null value), - * to read decoded base64 data.For other types of nodes, returns null. - * - * @return Binary data this node contains, iff it is a binary - * node; null otherwise - * @throws java.io.IOException Undocumented. - */ - public byte[] getBinaryValue() throws IOException - { - return null; - } - - public boolean getBooleanValue() { return false; } - - /** - * Returns numeric value for this node, if and only if - * this node is numeric ({@link #isNumber} returns true); otherwise - * returns null - * - * @return Number value this node contains, if any (null for non-number - * nodes). - */ - public Number getNumberValue() { return null; } - - public int getIntValue() { return 0; } - public long getLongValue() { return 0L; } - public double getDoubleValue() { return 0.0; } - public BigDecimal getDecimalValue() { return BigDecimal.ZERO; } - public BigInteger getBigIntegerValue() { return BigInteger.ZERO; } - - /** - * Method for accessing value of the specified element of - * an array node.For other nodes, null is always returned.

- * For array nodes, index specifies - * exact location within array and allows for efficient iteration - * over child elements (underlying storage is guaranteed to - * be efficiently indexable, i.e. has random-access to elements). - * If index is less than 0, or equal-or-greater than - * node.size(), null is returned; no exception is - * thrown for any index. - * - * @param index Undocumented. - * @return Node that represent value of the specified element, - * if this node is an array and has specified element. - * Null otherwise. - */ - public JsonNode get(int index) { return null; } - - /** - * Method for accessing value of the specified field of an object node.If this node is not an object (or it does not - * have a value for specified field name), or if there is no field with such name, null is returned. - * - * @param fieldName Undocumented. - * @return Node that represent value of the specified field, if this node is an object and has value for the - * specified field. Null otherwise. - */ - public JsonNode get(String fieldName) { return null; } - - /** - * Alias for {@link #get(String)}. - * - * @param fieldName Undocumented. - * @return Undocumented. - * @deprecated Use {@link #get(String)} instead. - */ - @Deprecated - public final JsonNode getFieldValue(String fieldName) { return get(fieldName); } - - /** - * Alias for {@link #get(int)}. - * - * @param index Undocumented. - * @return Undocumented. - * @deprecated Use {@link #get(int)} instead. - */ - @Deprecated - public final JsonNode getElementValue(int index) { return get(index); } - - - /** - * Method that will return valid String representation of - * the container value, if the node is a value node - * (method {@link #isValueNode} returns true), otherwise null. - *

- * Note: to serialize nodes of any type, you should call - * {@link #toString} instead. - * @return Undocumented. - */ - public abstract String getValueAsText(); - - /* - //////////////////////////////////////////////////// - // Public API, container access - //////////////////////////////////////////////////// - */ - - /** - * Method that returns number of child nodes this node contains: - * for Array nodes, number of child elements, for Object nodes, - * number of fields, and for all other nodes 0. - * - * @return For non-container nodes returns 0; for arrays number of - * contained elements, and for objects number of fields. - */ - public int size() { return 0; } - - /** - * Same as calling {@link #getElements}; implemented so that - * convenience "for-each" loop can be used for looping over elements - * of Json Array constructs. - */ - @Override - public final Iterator iterator() { return getElements(); } - - /** - * Method for accessing all value nodes of this Node, iff this node is a Json Array or Object node.In case of Object - * node, field names (keys) are not included, only values. For other types of nodes, returns empty iterator. - * - * @return Undocumented. - */ - public Iterator getElements() { return NO_NODES.iterator(); } - - /** - * Method for accessing names of all fields for this Node, iff - * this node is a Json Object node. - * @return Undocumented. - */ - public Iterator getFieldNames() { return NO_STRINGS.iterator(); } - - /* - //////////////////////////////////////////////////// - // Public API, path handling - //////////////////////////////////////////////////// - */ - - /** - * This method is similar to {@link #get(String)}, except that instead of returning null if no such value exists - * (due to this node not being an object, or object not having value for the specified field), a "missing node" - * (node that returns true for {@link #isMissingNode}) will be returned.This allows for convenient and safe chained - * access via path calls. - * - * @param fieldName Undocumented. - * @return Undocumented. - */ - public abstract JsonNode path(String fieldName); - - /** - * Alias of {@link #path(String)}. - * - * @param fieldName Undocumented. - * @return Undocumented. - * @deprecated Use {@link #path(String)} instead - */ - @Deprecated - public final JsonNode getPath(String fieldName) { return path(fieldName); } - - /** - * This method is similar to {@link #get(int)}, except that instead of returning null if no such element exists (due - * to index being out of range, or this node not being an array), a "missing node" (node that returns true for - * {@link #isMissingNode}) will be returned.This allows for convenient and safe chained access via path calls. - * - * @param index Undocumented. - * @return Undocumented. - */ - public abstract JsonNode path(int index); - - /** - * Alias of {@link #path(int)}. - * - * @param index Undocumented. - * @return Undocumented. - * @deprecated Use {@link #path(int)} instead - */ - @Deprecated - public final JsonNode getPath(int index) { return path(index); } - - /* - //////////////////////////////////////////////////// - // Public API, serialization - //////////////////////////////////////////////////// - */ - - /** - * Method that can be called to serialize this node and - * all of its descendants using specified JSON generator. - * - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - * @deprecated Use methods that are part of {@link JsonGenerator} - * or org.codehaus.jackson.map.ObjectMapper - * instead. - */ - @Deprecated - public abstract void writeTo(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API: converting to/from Streaming API - //////////////////////////////////////////////////// - */ - - - /** - * Method for constructing a {@link JsonParser} instance for iterating over contents of the tree that this node is - * root of.Functionally equivalent to first serializing tree using {@link #writeTo} and then re-parsing but much - * more efficient. - * - * @return Undocumented. - */ - public abstract JsonParser traverse(); - - /* - //////////////////////////////////////////////////// - // Overridden standard methods - //////////////////////////////////////////////////// - */ - - /** - *

- * Note: marked as abstract to ensure all implementation - * classes define it properly. - */ - @Override - public abstract String toString(); - - /** - *

- * Note: marked as abstract to ensure all implementation - * classes define it properly. - * @param o Undocumented. - */ - @Override - public abstract boolean equals(Object o); -} diff --git a/src/org/codehaus/jackson/JsonParseException.java b/src/org/codehaus/jackson/JsonParseException.java deleted file mode 100644 index 32038eeedd..0000000000 --- a/src/org/codehaus/jackson/JsonParseException.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.codehaus.jackson; - -/** - * Exception type for parsing problems, used when non-well-formed content - * (content that does not conform to JSON syntax as per specification) - * is encountered. - */ -public class JsonParseException - extends JsonProcessingException -{ - final static long serialVersionUID = 123; // Stupid eclipse... - - public JsonParseException(String msg, JsonLocation loc) - { - super(msg, loc); - } - - public JsonParseException(String msg, JsonLocation loc, Throwable root) - { - super(msg, loc, root); - } -} diff --git a/src/org/codehaus/jackson/JsonParser.java b/src/org/codehaus/jackson/JsonParser.java deleted file mode 100644 index dedc624767..0000000000 --- a/src/org/codehaus/jackson/JsonParser.java +++ /dev/null @@ -1,967 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codehaus.jackson; - -import java.io.*; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.codehaus.jackson.type.TypeReference; - -/** - * Base class that defines public API for reading JSON content. - * Instances are created using factory methods of - * a {@link JsonFactory} instance. - * - * @author Tatu Saloranta - */ -public abstract class JsonParser - implements Closeable -{ - private final static int MIN_BYTE_I = (int) Byte.MIN_VALUE; - private final static int MAX_BYTE_I = (int) Byte.MAX_VALUE; - - private final static int MIN_SHORT_I = (int) Short.MIN_VALUE; - private final static int MAX_SHORT_I = (int) Short.MAX_VALUE; - - /** - * Enumeration of possible "native" (optimal) types that can be - * used for numbers. - */ - public enum NumberType { - INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL - }; - - /** - * Enumeration that defines all togglable features for parsers. - */ - public enum Feature { - /** - * Feature that determines whether parser will automatically - * close underlying input source that is NOT owned by the - * parser. If disabled, calling application has to separately - * close the underlying {@link InputStream} and {@link Reader} - * instances used to create the parser. If enabled, parser - * will handle closing, as long as parser itself gets closed: - * this happens when end-of-input is encountered, or parser - * is closed by a call to {@link JsonParser#close}. - *

- * Feature is enabled by default. - */ - AUTO_CLOSE_SOURCE(true) - - /** - * Feature that determines whether parser will allow use - * of Java/C++ style comments (both '/'+'*' and - * '//' varieties) within parsed content or not. - *

- * Since JSON specification does not mention comments as legal - * construct, - * this is a non-standard feature; however, in the wild - * this is extensively used. As such, feature is - * disabled by default for parsers and must be - * explicitly enabled (via factory or parser instance). - *

- * This feature can be changed for parser instances. - */ - ,ALLOW_COMMENTS(false) - - /** - * Feature that determines whether parser will allow use - * of unquoted field names (which is allowed by Javascript, - * but not by JSON specification). - *

- * Since JSON specification requires use of double quotes for - * field names, - * this is a non-standard feature, and as such disabled by - * default. - *

- * This feature can be changed for parser instances. - * - * @since 1.2 - */ - ,ALLOW_UNQUOTED_FIELD_NAMES(false) - - /** - * Feature that determines whether parser will allow use - * of single quotes (apostrophe, character '\'') for - * quoting Strings (names and String values). If so, - * this is in addition to other acceptabl markers. - * but not by JSON specification). - *

- * Since JSON specification requires use of double quotes for - * field names, - * this is a non-standard feature, and as such disabled by - * default. - *

- * This feature can be changed for parser instances. - * - * @since 1.3 - */ - ,ALLOW_SINGLE_QUOTES(false) - - /** - * Feature that determines whether parser will allow - * JSON Strings to contain unquoted control characters - * (ASCII characters with value less than 32, including - * tab and line feed characters) or not. - * If feature is set false, an exception is thrown if such a - * character is encountered. - *

- * Since JSON specification requires quoting for all - * control characters, - * this is a non-standard feature, and as such disabled by - * default. - *

- * This feature can be changed for parser instances. - * - * @since 1.4 - */ - ,ALLOW_UNQUOTED_CONTROL_CHARS(false) - - /** - * Feature that determines whether JSON object field names are - * to be canonicalized using {@link String#intern} or not: - * if enabled, all field names will be intern()ed (and caller - * can count on this being true for all such names); if disabled, - * no intern()ing is done. There may still be basic - * canonicalization (that is, same String will be used to represent - * all identical object property names for a single document). - *

- * Note: this setting only has effect if - * {@link #CANONICALIZE_FIELD_NAMES} is true -- otherwise no - * canonicalization of any sort is done. - * - * @since 1.3 - */ - ,INTERN_FIELD_NAMES(true) - - /** - * Feature that determines whether JSON object field names are - * to be canonicalized (details of how canonicalization is done - * then further specified by - * {@link #INTERN_FIELD_NAMES}). - * - * @since 1.5 - */ - ,CANONICALIZE_FIELD_NAMES(true) - - // 14-Sep-2009, Tatu: This would be [JACKSON-142] implementation: - /* - * Feature that allows parser to recognize set of - * "Not-a-Number" (NaN) tokens as legal floating number - * values (similar to how many other data formats and - * programming language source code allows it). - * Specific subset contains values that - * XML Schema - * (see section 3.2.4.1, Lexical Representation) - * allows (tokens are quoted contents, not including quotes): - *

    - *
  • "INF" (for positive infinity) - *
  • "-INF" (for negative infinity) - *
  • "NaN" (for other not-a-numbers, like result of division by zero) - *
- - ,ALLOW_NON_NUMERIC_NUMBERS(false) - */ - - ; - - final boolean _defaultState; - - /** - * Method that calculates bit set (flags) of all features that - * are enabled by default. - * @return Undocumented. - */ - public static int collectDefaults() - { - int flags = 0; - for (Feature f : values()) { - if (f.enabledByDefault()) { - flags |= f.getMask(); - } - } - return flags; - } - - private Feature(boolean defaultState) { - _defaultState = defaultState; - } - - public boolean enabledByDefault() { return _defaultState; } - - public boolean enabledIn(int flags) { return (flags & getMask()) != 0; } - - public int getMask() { return (1 << ordinal()); } - }; - - /* - /*************************************************** - /* Minimal configuration state - /*************************************************** - */ - - /** - * Bit flag composed of bits that indicate which - * {@link org.codehaus.jackson.JsonParser.Feature}s - * are enabled. - */ - protected int _features; - - /* - /*************************************************** - /* Minimal generic state - /*************************************************** - */ - - /** - * Last token retrieved via {@link #nextToken}, if any. - * Null before the first call to nextToken(), - * as well as if token has been explicitly cleared - * (by call to {@link #clearCurrentToken}) - */ - protected JsonToken _currToken; - - /** - * Last cleared token, if any: that is, value that was in - * effect when {@link #clearCurrentToken} was called. - */ - protected JsonToken _lastClearedToken; - - /* - /*************************************************** - /* Construction, init - /*************************************************** - */ - - protected JsonParser() { } - - /** - * Accessor for {@link ObjectCodec} associated with this parser, if any.Codec is used by {@link #readValueAs(Class)} - * method (and its variants). - * - * @return Undocumented. - * @since 1.3 - */ - public abstract ObjectCodec getCodec(); - - /** - * Setter that allows defining {@link ObjectCodec} associated with this parser, if any.Codec is used by - * {@link #readValueAs(Class)} method (and its variants). - * - * @param c Undocumented. - * @since 1.3 - */ - public abstract void setCodec(ObjectCodec c); - - /* - /*************************************************** - /* Closeable implementation - /*************************************************** - */ - - /** - * Closes the parser so that no further iteration or data access - * can be made; will also close the underlying input source - * if parser either owns the input source, or feature - * {@link Feature#AUTO_CLOSE_SOURCE} is enabled. - * Whether parser owns the input source depends on factory - * method that was used to construct instance (so check - * {@link org.codehaus.jackson.JsonFactory} for details, - * but the general - * idea is that if caller passes in closable resource (such - * as {@link InputStream} or {@link Reader}) parser does NOT - * own the source; but if it passes a reference (such as - * {@link java.io.File} or {@link java.net.URL} and creates - * stream or reader it does own them. - */ - @Override - public abstract void close() throws IOException; - - /* - /*************************************************** - /* Public API, configuration - /*************************************************** - */ - - /** - * Method for enabling specified parser feature - * (check {@link Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonParser enable(Feature f) - { - _features |= f.getMask(); - return this; - } - - /** - * Method for disabling specified feature - * (check {@link Feature} for list of features) - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonParser disable(Feature f) - { - _features &= ~f.getMask(); - return this; - } - - /** - * Method for enabling or disabling specified feature - * (check {@link Feature} for list of features) - * - * @param f Undocumented. - * @param state Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public JsonParser configure(Feature f, boolean state) - { - if (state) { - enableFeature(f); - } else { - disableFeature(f); - } - return this; - } - - /** - * Method for checking whether specified {@link Feature} - * is enabled. - * - * @param f Undocumented. - * @return Undocumented. - * @since 1.2 - */ - public boolean isEnabled(Feature f) { - return (_features & f.getMask()) != 0; - } - - /** - * @deprecated Use {@link #configure} instead - * @param f Undocumented. - * @param state Undocumented. - */ - @Deprecated - public void setFeature(Feature f, boolean state) { configure(f, state); } - - /** - * @deprecated Use {@link #enable(Feature)} instead - * @param f Undocumented. - */ - @Deprecated - public void enableFeature(Feature f) { enable(f); } - - /** - * @param f Undocumented. - * @deprecated Use {@link #disable(Feature)} instead - */ - @Deprecated - public void disableFeature(Feature f) { disable(f); } - - /** - * @param f Undocumented. - * @return Undocumented. - * @deprecated Use {@link #isEnabled(Feature)} instead - */ - @Deprecated - public final boolean isFeatureEnabled(Feature f) { return isEnabled(f); } - - - /* - /*************************************************** - /* Public API, traversal - /*************************************************** - */ - - /** - * Main iteration method, which will advance stream enough to determine type of the next token, if any.If none - * remaining (stream has no content other than possible white space before ending), null will be returned. - * - * @return Next token from the stream, if any found, or null to indicate end-of-input - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract JsonToken nextToken() - throws IOException, JsonParseException; - - /** - * Iteration method that will advance stream enough to determine type of the next token that is a value type - * (including Json Array and Object start/end markers).Or put another way, nextToken() will be called once, and if - * {@link JsonToken#FIELD_NAME} is returned, another time to get the value for the field.Method is most useful for - * iterating over value entries of Json objects; field name will still be available by calling - * {@link #getCurrentName} when parser points to the value. - * - * @return Next non-field-name token from the stream, if any found, or null to indicate end-of-input (or, for - * non-blocking parsers, {@link JsonToken#NOT_AVAILABLE} if no tokens were available yet) - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * - * @since 0.9.7 - */ - public JsonToken nextValue() - throws IOException, JsonParseException - { - /* Implementation should be as trivial as follows; only - * needs to change if we are to skip other tokens (for - * example, if comments were exposed as tokens) - */ - JsonToken t = nextToken(); - if (t == JsonToken.FIELD_NAME) { - t = nextToken(); - } - return t; - } - - /** - * Method that will skip all child tokens of an array or object token that the parser currently points to, iff - * stream points to {@link JsonToken#START_OBJECT} or {@link JsonToken#START_ARRAY}.If not, it will do nothing.After - * skipping, stream will point to matching {@link JsonToken#END_OBJECT} or {@link JsonToken#END_ARRAY} - * (possibly skipping nested pairs of START/END OBJECT/ARRAY tokens as well as value tokens).The idea is that after - * calling this method, application will call {@link #nextToken} to point to the next available token, if any. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract JsonParser skipChildren() - throws IOException, JsonParseException; - - /** - * Method that can be called to determine whether this parser is closed or not.If it is closed, no new tokens can be - * retrieved by calling {@link #nextToken} (and the underlying stream may be closed). Closing may be due to an - * explicit call to {@link #close} or because parser has encountered end of input. - * - * @return Undocumented. - */ - public abstract boolean isClosed(); - - /* - /*************************************************** - /* Public API, token accessors - /*************************************************** - */ - - /** - * Accessor to find which token parser currently points to, if any; - * null will be returned if none. - * If return value is non-null, data associated with the token - * is available via other accessor methods. - * - * @return Type of the token this parser currently points to, - * if any: null before any tokens have been read, and - * after end-of-input has been encountered, as well as - * if the current token has been explicitly cleared. - */ - public JsonToken getCurrentToken() { - return _currToken; - } - - /** - * Method for checking whether parser currently points to - * a token (and data for that token is available). - * Equivalent to check for parser.getCurrentToken() != null. - * - * @return True if the parser just returned a valid - * token via {@link #nextToken}; false otherwise (parser - * was just constructed, encountered end-of-input - * and returned null from {@link #nextToken}, or the token - * has been consumed) - */ - public boolean hasCurrentToken() { - return _currToken != null; - } - - - /** - * Method called to "consume" the current token by effectively - * removing it so that {@link #hasCurrentToken} returns false, and - * {@link #getCurrentToken} null). - * Cleared token value can still be accessed by calling - * {@link #getLastClearedToken} (if absolutely needed), but - * usually isn't. - *

- * Method was added to be used by the optional data binder, since - * it has to be able to consume last token used for binding (so that - * it will not be used again). - */ - public void clearCurrentToken() { - if (_currToken != null) { - _lastClearedToken = _currToken; - _currToken = null; - } - } - - /** - * Method that can be called to get the name associated with - * the current token: for {@link JsonToken#FIELD_NAME}s it will - * be the same as what {@link #getText} returns; - * for field values it will be preceding field name; - * and for others (array values, root-level values) null. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract String getCurrentName() - throws IOException, JsonParseException; - - /** - * Method that can be used to access current parsing context reader is in.There are 3 different types: root, array - * and object contexts, with slightly different available information. Contexts are hierarchically nested, and can - * be used for example for figuring out part of the input document that correspond to specific array or object (for - * highlighting purposes, or error reporting). Contexts can also be used for simple xpath-like matching of input, if - * so desired. - * - * @return Undocumented. - */ - public abstract JsonStreamContext getParsingContext(); - - /** - * Method that return the starting location of the current - * token; that is, position of the first character from input - * that starts the current token. - * @return Undocumented. - */ - public abstract JsonLocation getTokenLocation(); - - /** - * Method that returns location of the last processed character; - * usually for error reporting purposes. - * @return Undocumented. - */ - public abstract JsonLocation getCurrentLocation(); - - /** - * Method that can be called to get the last token that was cleared using {@link #clearCurrentToken}.This is not - * necessarily the latest token read. Will return null if no tokens have been cleared, or if parser has been closed. - * - * @return Undocumented. - */ - public JsonToken getLastClearedToken() { - return _lastClearedToken; - } - - /* - /*************************************************** - /* Public API, access to token information, text - /*************************************************** - */ - - /** - * Method for accessing textual representation of the current token; - * if no current token (before first call to {@link #nextToken}, or - * after encountering end-of-input), returns null.Method can be called for any token type. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract String getText() - throws IOException, JsonParseException; - - /** - * Method similar to {@link #getText}, but that will return underlying (unmodifiable) character array that contains - * textual value, instead of constructing a String object to contain this information.Note, however, that: - *

    - *
  • Textual contents are not guaranteed to start at index 0 (rather, call {@link #getTextOffset}) to know the - * actual offset - *
  • - *
  • Length of textual contents may be less than the length of returned buffer: call {@link #getTextLength} for - * actual length of returned content.
  • - *
- *

- * Note that caller MUST NOT modify the returned character array in any way -- doing so may corrupt current - * parser state and render parser instance useless. - *

- * The only reason to call this method (over {@link #getText}) is to avoid construction of a String object (which - * will make a copy of contents). - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract char[] getTextCharacters() - throws IOException, JsonParseException; - - /** - * Accessor used with {@link #getTextCharacters}, to know length - * of String stored in returned buffer. - * - * @return Number of characters within buffer returned - * by {@link #getTextCharacters} that are part of - * textual content of the current token. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract int getTextLength() - throws IOException, JsonParseException; - - /** - * Accessor used with {@link #getTextCharacters}, to know offset - * of the first text content character within buffer. - * - * @return Offset of the first character within buffer returned - * by {@link #getTextCharacters} that is part of - * textual content of the current token. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract int getTextOffset() - throws IOException, JsonParseException; - - /* - /*************************************************** - /* Public API, access to token information, numeric - /*************************************************** - */ - - /** - * Generic number value accessor method that will work for all kinds of numeric values.It will return the optimal - * (simplest/smallest possibl) wrapper object that can express the numeric value just parsed. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract Number getNumberValue() - throws IOException, JsonParseException; - - /** - * If current token is of type - * {@link JsonToken#VALUE_NUMBER_INT} or - * {@link JsonToken#VALUE_NUMBER_FLOAT}, returns - * one of {@link NumberType} constants; otherwise returns null. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract NumberType getNumberType() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_INT} and it - * can be expressed as a value of Java byte primitive type.It can also be called for - * {@link JsonToken#VALUE_NUMBER_FLOAT}; if so, it is equivalent to calling {@link #getDoubleValue} and then - * casting; except for possible overflow/underflow exception.

- * Note: if the resulting integer value falls outside range of Java byte, a {@link JsonParseException} will be - * thrown to indicate numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public byte getByteValue() - throws IOException, JsonParseException - { - int value = getIntValue(); - // So far so good: but does it fit? - if (value < MIN_BYTE_I || value > MAX_BYTE_I) { - throw _constructError("Numeric value ("+getText()+") out of range of Java byte"); - } - return (byte) value; - } - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_INT} and it - * can be expressed as a value of Java short primitive type.It can also be called for - * {@link JsonToken#VALUE_NUMBER_FLOAT}; if so, it is equivalent to calling {@link #getDoubleValue} and then - * casting; except for possible overflow/underflow exception.

- * Note: if the resulting integer value falls outside range of Java short, a {@link JsonParseException} will be - * thrown to indicate numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public short getShortValue() - throws IOException, JsonParseException - { - int value = getIntValue(); - if (value < MIN_SHORT_I || value > MAX_SHORT_I) { - throw _constructError("Numeric value ("+getText()+") out of range of Java short"); - } - return (short) value; - } - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_INT} and it - * can be expressed as a value of Java int primitive type.It can also be called for - * {@link JsonToken#VALUE_NUMBER_FLOAT}; if so, it is equivalent to calling {@link #getDoubleValue} and then - * casting; except for possible overflow/underflow exception.

- * Note: if the resulting integer value falls outside range of Java int, a {@link JsonParseException} may be thrown - * to indicate numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract int getIntValue() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_INT} and it - * can be expressed as a Java long primitive type.It can also be called for {@link JsonToken#VALUE_NUMBER_FLOAT}; if - * so, it is equivalent to calling {@link #getDoubleValue} and then casting to int; except for possible - * overflow/underflow exception.

- * Note: if the token is an integer, but its value falls outside of range of Java long, a {@link JsonParseException} - * may be thrown to indicate numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract long getLongValue() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_INT} and it - * can not be used as a Java long primitive type due to its magnitude.It can also be called for - * {@link JsonToken#VALUE_NUMBER_FLOAT}; if so, it is equivalent to calling {@link #getDecimalValue} and then - * constructing a {@link BigInteger} from that value. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract BigInteger getBigIntegerValue() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_FLOAT} and it - * can be expressed as a Java float primitive type.It can also be called for {@link JsonToken#VALUE_NUMBER_INT}; if - * so, it is equivalent to calling {@link #getLongValue} and then casting; except for possible overflow/underflow - * exception.

- * Note: if the value falls outside of range of Java float, a {@link JsonParseException} will be thrown to indicate - * numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract float getFloatValue() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_FLOAT} and it - * can be expressed as a Java double primitive type.It can also be called for {@link JsonToken#VALUE_NUMBER_INT}; if - * so, it is equivalent to calling {@link #getLongValue} and then casting; except for possible overflow/underflow - * exception.

- * Note: if the value falls outside of range of Java double, a {@link JsonParseException} will be thrown to indicate - * numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract double getDoubleValue() - throws IOException, JsonParseException; - - /** - * Numeric accessor that can be called when the current token is of type {@link JsonToken#VALUE_NUMBER_FLOAT} or - * {@link JsonToken#VALUE_NUMBER_INT}.No under/overflow exceptions are ever thrown. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract BigDecimal getDecimalValue() - throws IOException, JsonParseException; - - /** - * Convenience accessor that can be called when the current token is {@link JsonToken#VALUE_TRUE} or - * {@link JsonToken#VALUE_FALSE}. - *

- * Note: if the token is not of above-mentioned boolean types, an integer, but its value falls outside of range of - * Java long, a {@link JsonParseException} may be thrown to indicate numeric overflow/underflow. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * @since 1.3 - */ - public boolean getBooleanValue() - throws IOException, JsonParseException - { - if (_currToken == JsonToken.VALUE_TRUE) return true; - if (_currToken == JsonToken.VALUE_FALSE) return false; - throw new JsonParseException("Current token ("+_currToken+") not of boolean type", getCurrentLocation()); - } - - /** - * Accessor that can be called if (and only if) the current token is {@link JsonToken#VALUE_EMBEDDED_OBJECT}.For - * other token types, null is returned.

- * Note: only some specialized parser implementations support embedding of objects (usually ones that are facades on - * top of non-streaming sources, such as object trees). - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * @since 1.3 - */ - public Object getEmbeddedObject() - throws IOException, JsonParseException - { - // By default we will always return null - return null; - } - - /* - /*************************************************** - /* Public API, access to token information, binary - /*************************************************** - */ - - /** - * Method that can be used to read (and consume -- results may not be accessible using other methods after the call) - * base64-encoded binary data included in the current textual json value.It works similar to getting String value - * via {@link #getText} and decoding result (except for decoding part), but should be significantly more - * performant.

- * Note that non-decoded textual contents of the current token are not guaranteed to be accessible after this method - * is called. Current implementation, for example, clears up textual content during decoding. Decoded binary - * content, however, will be retained until parser is advanced to the next event. - * - * @param b64variant Expected variant of base64 encoded content (see {@link Base64Variants} for definitions of - * "standard" variants). - * - * @return Decoded binary data - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public abstract byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException; - - /** - * Convenience alternative to {@link #getBinaryValue(Base64Variant)} - * that defaults to using - * {@link Base64Variants#getDefaultVariant} as the default encoding. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public byte[] getBinaryValue() throws IOException, JsonParseException - { - return getBinaryValue(Base64Variants.getDefaultVariant()); - } - - /* - /*************************************************** - /* Public API, optional data binding functionality - /*************************************************** - */ - - /** - * Method to deserialize Json content into a non-container type (it can be an array type, however): typically a - * bean, array or a wrapper type (like {@link java.lang.Boolean}).Note: method can only be called if the - * parser has an object codec assigned; this is true for parsers constructed by - * org.codehaus.jackson.map.MappingJsonFactory but not for {@link JsonFactory} (unless its - * setCodec method has been explicitly called) - * .

- * This method may advance the event stream, for structured types the current token will be the closing end marker - * (END_ARRAY, END_OBJECT) of the bound structure. For non-structured Json types (and for - * {@link JsonToken#VALUE_EMBEDDED_OBJECT}) stream is not advanced. - *

- * Note: this method should NOT be used if the result type is a container ({@link java.util.Collection} or - * {@link java.util.Map}. The reason is that due to type erasure, key and value types can not be introspected when - * using this method. - * - * @param Undocumented. - * @param valueType Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public T readValueAs(Class valueType) - throws IOException, JsonProcessingException - { - ObjectCodec codec = getCodec(); - if (codec == null) { - throw new IllegalStateException("No ObjectCodec defined for the parser, can not deserialize JSON into Java objects"); - } - return codec.readValue(this, valueType); - } - - /** - * Method to deserialize Json content into a Java type, reference to which is passed as argument.Type is passed - * using so-called "super type token" and specifically needs to be used if the root type is a parameterized - * (generic) container type.Note: method can only be called if the parser has an object codec assigned; this - * is true for parsers constructed by org.codehaus.jackson.map.MappingJsonFactory but not for - * {@link JsonFactory} (unless its setCodec method has been explicitly called). - *

- * This method may advance the event stream, for structured types the current token will be the closing end marker - * (END_ARRAY, END_OBJECT) of the bound structure. For non-structured Json types (and for - * {@link JsonToken#VALUE_EMBEDDED_OBJECT}) stream is not advanced. - * - * @param Undocumented. - * @param valueTypeRef Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - @SuppressWarnings("unchecked") - public T readValueAs(TypeReference valueTypeRef) - throws IOException, JsonProcessingException - { - ObjectCodec codec = getCodec(); - if (codec == null) { - throw new IllegalStateException("No ObjectCodec defined for the parser, can not deserialize JSON into Java objects"); - } - /* Ugh. Stupid Java type erasure... can't just chain call,s - * must cast here also. - */ - return (T) codec.readValue(this, valueTypeRef); - } - - /** - * Method to deserialize Json content into equivalent "tree model", represented by root {@link JsonNode} of - * resulting model.For Json Arrays it will an array node (with child nodes), for objects object node (with child - * nodes), and for other types matching leaf node type - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public JsonNode readValueAsTree() - throws IOException, JsonProcessingException - { - ObjectCodec codec = getCodec(); - if (codec == null) { - throw new IllegalStateException("No ObjectCodec defined for the parser, can not deserialize JSON into JsonNode tree"); - } - return codec.readTree(this); - } - - /* - /*************************************************** - /* Internal methods - /*************************************************** - */ - - /** - * Helper method for constructing {@link JsonParseException}s - * based on current state of the parser - * @param msg Undocumented. - * @return Undocumented. - */ - protected JsonParseException _constructError(String msg) - { - return new JsonParseException(msg, getCurrentLocation()); - } -} diff --git a/src/org/codehaus/jackson/JsonProcessingException.java b/src/org/codehaus/jackson/JsonProcessingException.java deleted file mode 100644 index 329b4717dc..0000000000 --- a/src/org/codehaus/jackson/JsonProcessingException.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.codehaus.jackson; - -/** - * Intermediate base class for all problems encountered when - * processing (parsing, generating) JSON content - * that are not pure I/O problems. - * Regular {@link java.io.IOException}s will be passed through as is. - * Sub-class of {@link java.io.IOException} for convenience. - */ -public class JsonProcessingException - extends java.io.IOException -{ - final static long serialVersionUID = 123; // Stupid eclipse... - - protected JsonLocation mLocation; - - protected JsonProcessingException(String msg, JsonLocation loc, Throwable rootCause) - { - /* Argh. IOException(Throwable,String) is only available starting - * with JDK 1.6... - */ - super(msg); - if (rootCause != null) { - initCause(rootCause); - } - mLocation = loc; - } - - protected JsonProcessingException(String msg) - { - super(msg); - } - - protected JsonProcessingException(String msg, JsonLocation loc) - { - this(msg, loc, null); - } - - protected JsonProcessingException(String msg, Throwable rootCause) - { - this(msg, null, rootCause); - } - - protected JsonProcessingException(Throwable rootCause) - { - this(null, null, rootCause); - } - - public JsonLocation getLocation() - { - return mLocation; - } - - /** - * Default method overridden so that we can add location information - */ - @Override - public String getMessage() - { - String msg = super.getMessage(); - if (msg == null) { - msg = "N/A"; - } - JsonLocation loc = getLocation(); - if (loc != null) { - StringBuilder sb = new StringBuilder(); - sb.append(msg); - sb.append('\n'); - sb.append(" at "); - sb.append(loc.toString()); - return sb.toString(); - } - return msg; - } - - @Override - public String toString() { - return getClass().getName()+": "+getMessage(); - } -} diff --git a/src/org/codehaus/jackson/JsonStreamContext.java b/src/org/codehaus/jackson/JsonStreamContext.java deleted file mode 100644 index e785517fec..0000000000 --- a/src/org/codehaus/jackson/JsonStreamContext.java +++ /dev/null @@ -1,115 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codehaus.jackson; - -/** - * Shared base class for streaming processing contexts used during - * reading and writing of Json content using Streaming API. - * This context is also exposed to applications: - * context object can be used by applications to get an idea of - * relative position of the parser/generator within json content - * being processed. This allows for some contextual processing: for - * example, output within Array context can differ from that of - * Object context. - */ -public abstract class JsonStreamContext -{ - // // // Type constants used internally - - protected final static int TYPE_ROOT = 0; - protected final static int TYPE_ARRAY = 1; - protected final static int TYPE_OBJECT = 2; - - protected int _type; - - /** - * Index of the currently processed entry. Starts with -1 to signal - * that no entries have been started, and gets advanced each - * time a new entry is started, either by encountering an expected - * separator, or with new values if no separators are expected - * (the case for root context). - */ - protected int _index; - - /* - ////////////////////////////////////////////////// - // Life-cycle - ////////////////////////////////////////////////// - */ - - public JsonStreamContext(int type) - { - _type = type; - _index = -1; - } - - /* - ////////////////////////////////////////////////// - // Public API, accessors - ////////////////////////////////////////////////// - */ - - public abstract JsonStreamContext getParent(); - - /** - * Method that returns true if this context is an Array context; - * that is, content is being read from or written to a Json Array. - * @return Undocumented. - */ - public final boolean inArray() { return _type == TYPE_ARRAY; } - - /** - * Method that returns true if this context is a Root context; - * that is, content is being read from or written to without - * enclosing array or object structure. - * @return Undocumented. - */ - public final boolean inRoot() { return _type == TYPE_ROOT; } - - /** - * Method that returns true if this context is an Object context; - * that is, content is being read from or written to a Json Object. - * @return Undocumented. - */ - public final boolean inObject() { return _type == TYPE_OBJECT; } - - public final String getTypeDesc() { - switch (_type) { - case TYPE_ROOT: return "ROOT"; - case TYPE_ARRAY: return "ARRAY"; - case TYPE_OBJECT: return "OBJECT"; - } - return "?"; - } - - /** - * @return Number of entries that are complete and started. - */ - public final int getEntryCount() - { - return _index + 1; - } - - /** - * @return Index of the currently processed entry, if any - */ - public final int getCurrentIndex() - { - return (_index < 0) ? 0 : _index; - } - - public abstract String getCurrentName(); -} diff --git a/src/org/codehaus/jackson/JsonToken.java b/src/org/codehaus/jackson/JsonToken.java deleted file mode 100644 index 09507c37dc..0000000000 --- a/src/org/codehaus/jackson/JsonToken.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.codehaus.jackson; - -/** - * Enumeration for basic token types used for returning results - * of parsing JSON content. - */ -public enum JsonToken -{ - /* Some notes on implementation: - * - * - Entries are to be ordered such that start/end array/object - * markers come first, then field name marker (if any), and - * finally scalar value tokens. This is assumed by some - * typing checks. - */ - - /** - * NOT_AVAILABLE can be returned if {@link JsonParser} - * implementation can not currently return the requested - * token (usually next one), or even if any will be - * available, but that may be able to determine this in - * future. This is the case with non-blocking parsers -- - * they can not block to wait for more data to parse and - * must return something. - * - * @since 0.9.7 - */ - NOT_AVAILABLE(null), - - /** - * START_OBJECT is returned when encountering '{' - * which signals starting of an Object value. - */ - START_OBJECT("{"), - - /** - * START_OBJECT is returned when encountering '}' - * which signals ending of an Object value - */ - END_OBJECT("}"), - - /** - * START_OBJECT is returned when encountering '[' - * which signals starting of an Array value - */ - START_ARRAY("["), - - /** - * START_OBJECT is returned when encountering ']' - * which signals ending of an Array value - */ - END_ARRAY("]"), - - /** - * FIELD_NAME is returned when a String token is encountered - * as a field name (same lexical value, different function) - */ - FIELD_NAME(null), - - /** - * Placeholder token returned when the input source has a concept - * of embedded Object that are not accessible as usual structure - * (of starting with {@link #START_OBJECT}, having values, ending with - * {@link #END_OBJECT}), but as "raw" objects. - *

- * Note: this token is never returned by regular JSON readers, but - * only by readers that expose other kinds of source (like - * {@link JsonNode}-based JSON trees, Maps, Lists and such). - * - * @since 1.1 - */ - VALUE_EMBEDDED_OBJECT(null), - - /** - * VALUE_STRING is returned when a String token is encountered - * in value context (array element, field value, or root-level - * stand-alone value) - */ - VALUE_STRING(null), - - /** - * VALUE_NUMBER_INT is returned when an integer numeric token is - * encountered in value context: that is, a number that does - * not have floating point or exponent marker in it (consists - * only of an optional sign, followed by one or more digits) - */ - VALUE_NUMBER_INT(null), - - /** - * VALUE_NUMBER_INT is returned when a numeric token other - * that is not an integer is encountered: that is, a number that does - * have floating point or exponent marker in it, in addition - * to one or more digits. - */ - VALUE_NUMBER_FLOAT(null), - - /** - * VALUE_TRUE is returned when encountering literal "true" in - * value context - */ - VALUE_TRUE("true"), - - /** - * VALUE_FALSE is returned when encountering literal "false" in - * value context - */ - VALUE_FALSE("false"), - - /** - * VALUE_NULL is returned when encountering literal "null" in - * value context - */ - VALUE_NULL("null") - ; - - final String _serialized; - - final char[] _serializedChars; - - final byte[] _serializedBytes; - - /** - * @param Textual representation for this token, if there is a - * single static representation; null otherwise - */ - JsonToken(String token) - { - if (token == null) { - _serialized = null; - _serializedChars = null; - _serializedBytes = null; - } else { - _serialized = token; - _serializedChars = token.toCharArray(); - // It's all in ascii, can just case... - int len = _serializedChars.length; - _serializedBytes = new byte[len]; - for (int i = 0; i < len; ++i) { - _serializedBytes[i] = (byte) _serializedChars[i]; - } - } - } - - public String asString() { return _serialized; } - public char[] asCharArray() { return _serializedChars; } - public byte[] asByteArray() { return _serializedBytes; } - - public boolean isNumeric() { - return (this == VALUE_NUMBER_INT) || (this == VALUE_NUMBER_FLOAT); - } - - /** - * Method that can be used to check whether this token represents a valid non-structured value.This means all tokens - * other than Object/Array start/end markers all field names. - * - * @return Undocumented. - */ - public boolean isScalarValue() { - return ordinal() >= VALUE_STRING.ordinal(); - } -} diff --git a/src/org/codehaus/jackson/ObjectCodec.java b/src/org/codehaus/jackson/ObjectCodec.java deleted file mode 100644 index ed06bd898b..0000000000 --- a/src/org/codehaus/jackson/ObjectCodec.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.codehaus.jackson; - -import java.io.IOException; - -import org.codehaus.jackson.type.JavaType; -import org.codehaus.jackson.type.TypeReference; - -/** - * Abstract class that defines the interface that {@link JsonParser} and - * {@link JsonGenerator} use to serialize and deserialize regular - * Java objects (POJOs aka Beans). - */ -public abstract class ObjectCodec -{ - protected ObjectCodec() { } - - /* - ///////////////////////////////////////////////// - // API for serialization (Object-to-JSON) - ///////////////////////////////////////////////// - */ - - /** - * Method to deserialize JSON content into a non-container - * type (it can be an array type, however): typically a bean, array - * or a wrapper type (like {@link java.lang.Boolean}). - *

- * Note: this method should NOT be used if the result type is a - * container ({@link java.util.Collection} or {@link java.util.Map}. - * The reason is that due to type erasure, key and value types - * can not be introspected when using this method. - * @param Undocumented. - * @param jp Undocumented. - * @param valueType Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract T readValue(JsonParser jp, Class valueType) - throws IOException, JsonProcessingException; - - /** - * Method to deserialize JSON content into a Java type, reference to which is passed as argument.Type is passed - * using so-called "super type token" (see ) and specifically needs to be used if the root type is a parameterized - * (generic) container type. - * - * @param Undocumented. - * @param jp Undocumented. - * @param valueTypeRef Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract T readValue(JsonParser jp, TypeReference valueTypeRef) - throws IOException, JsonProcessingException; - - /** - * Method to deserialize JSON content as tree expressed - * using set of {@link JsonNode} instances.Returns - root of the resulting tree (where root can consist - of just a single node if the current event is a - value event, not container). - * @param Undocumented. - * @param jp Undocumented. - * @param valueType Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract T readValue(JsonParser jp, JavaType valueType) - throws IOException, JsonProcessingException; - - /** - * Method to deserialize JSON content as tree expressed - * using set of {@link JsonNode} instances.Returns - root of the resulting tree (where root can consist - of just a single node if the current event is a - value event, not container). - * @param jp Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract JsonNode readTree(JsonParser jp) - throws IOException, JsonProcessingException; - - /* - ///////////////////////////////////////////////// - // API for de-serialization (Json-to-Object) - ///////////////////////////////////////////////// - */ - - /** - * Method to serialize given Java Object, using generator - * provided. - * @param jgen Undocumented. - * @param value Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract void writeValue(JsonGenerator jgen, Object value) - throws IOException, JsonProcessingException; - - /** - * Method to serialize given Json Tree, using generator - * provided. - * @param jgen Undocumented. - * @param rootNode Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - */ - public abstract void writeTree(JsonGenerator jgen, JsonNode rootNode) - throws IOException, JsonProcessingException; - - /* - ///////////////////////////////////////////////// - // API for Tree Model handling - ///////////////////////////////////////////////// - */ - - /** - * Method for construct root level Object nodes - * for Tree Model instances. - * - * @return Undocumented. - * @since 1.2 - */ - public abstract JsonNode createObjectNode(); - - /** - * Method for construct root level Array nodes - * for Tree Model instances. - * - * @return Undocumented. - * @since 1.2 - */ - public abstract JsonNode createArrayNode(); - - /** - * Method for constructing a {@link JsonParser} for reading - * contents of a JSON tree, as if it was external serialized - * JSON content. - * - * @param n Undocumented. - * @return Undocumented. - * @since 1.3 - */ - public abstract JsonParser treeAsTokens(JsonNode n); - - /* - * Method for constructing a {@link JsonGenerator} that can - * be used to add content to a JSON tree. - * - * @param containerNode Container node to add contents to via created generator. - * If node is not a container node (as per {@link JsonNode#isContainerNode}), - * {@link IllegalArgumentException} will be thrown - * -c public abstract JsonGenerator treeFromTokens(JsonNode containerNode) - throws IllegalArgumentException; - */ - - /** - * Convenience method for converting given JSON tree into instance of specified value type.This is equivalent to - * first constructing a {@link JsonParser} to iterate over contents of the tree, and using that parser for data - * binding. - * - * @param Undocumented. - * @param n Undocumented. - * @param valueType Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonProcessingException Undocumented. - * @since 1.3 - */ - public abstract T treeToValue(JsonNode n, Class valueType) - throws IOException, JsonProcessingException; -} diff --git a/src/org/codehaus/jackson/PrettyPrinter.java b/src/org/codehaus/jackson/PrettyPrinter.java deleted file mode 100644 index c50b1333eb..0000000000 --- a/src/org/codehaus/jackson/PrettyPrinter.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.codehaus.jackson; - -import java.io.IOException; - -/** - * Interface for objects that implement pretty printer functionality, such - * as indentation. - * Pretty printers are used to add white space in output JSON content, - * to make results more human readable. Usually this means things like adding - * linefeeds and indentation. - */ -public interface PrettyPrinter -{ - /* - ////////////////////////////////////////////////////// - // First methods that act both as events, and expect - // output for correct functioning (i.e something gets - // output even when not pretty-printing) - ////////////////////////////////////////////////////// - */ - - // // // Root-level handling: - - /** - * Method called after a root-level value has been completely - * output, and before another value is to be output. - *

- * Default - * handling (without pretty-printing) will output a space, to - * allow values to be parsed correctly. Pretty-printer is - * to output some other suitable and nice-looking separator - * (tab(s), space(s), linefeed(s) or any combination thereof). - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeRootValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException; - - // // Object handling - - /** - * Method called when an Object value is to be output, before - * any fields are output. - *

- * Default handling (without pretty-printing) will output - * the opening curly bracket. - * Pretty-printer is - * to output a curly bracket as well, but can surround that - * with other (white-space) decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeStartObject(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /** - * Method called after an Object value has been completely output - * (minus closing curly bracket). - *

- * Default handling (without pretty-printing) will output - * the closing curly bracket. - * Pretty-printer is - * to output a curly bracket as well, but can surround that - * with other (white-space) decoration. - * - * @param jg Undocumented. - * @param nrOfEntries Number of direct members of the array that - * have been output - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeEndObject(JsonGenerator jg, int nrOfEntries) - throws IOException, JsonGenerationException; - - /** - * Method called after an object entry (field:value) has been completely - * output, and before another value is to be output. - *

- * Default handling (without pretty-printing) will output a single - * comma to separate the two. Pretty-printer is - * to output a comma as well, but can surround that with other - * (white-space) decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeObjectEntrySeparator(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /** - * Method called after an object field has been output, but - * before the value is output. - *

- * Default handling (without pretty-printing) will output a single - * colon to separate the two. Pretty-printer is - * to output a colon as well, but can surround that with other - * (white-space) decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeObjectFieldValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException; - - // // // Array handling - - /** - * Method called when an Array value is to be output, before - * any member/child values are output. - *

- * Default handling (without pretty-printing) will output - * the opening bracket. - * Pretty-printer is - * to output a bracket as well, but can surround that - * with other (white-space) decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeStartArray(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /** - * Method called after an Array value has been completely output - * (minus closing bracket). - *

- * Default handling (without pretty-printing) will output - * the closing bracket. - * Pretty-printer is - * to output a bracket as well, but can surround that - * with other (white-space) decoration. - * - * @param jg Undocumented. - * @param nrOfValues Number of direct members of the array that - * have been output - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeEndArray(JsonGenerator jg, int nrOfValues) - throws IOException, JsonGenerationException; - - /** - * Method called after an array value has been completely - * output, and before another value is to be output. - *

- * Default handling (without pretty-printing) will output a single - * comma to separate the two. Pretty-printer is - * to output a comma as well, but can surround that with other - * (white-space) decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void writeArrayValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /* - ////////////////////////////////////////////////////// - // Then events that by default do not produce any output - // but that are often overridden to add white space - // in pretty-printing mode - ////////////////////////////////////////////////////// - */ - - /** - * Method called after array start marker has been output, - * and right before the first value is to be output.It is not called for arrays with no values.

- * Default handling does not output anything, but pretty-printer - * is free to add any white space decoration. - * @param jg Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void beforeArrayValues(JsonGenerator jg) - throws IOException, JsonGenerationException; - - /** - * Method called after object start marker has been output, - * and right before the field name of the first entry is - * to be output.It is not called for objects without entries.

- * Default handling does not output anything, but pretty-printer - * is free to add any white space decoration. - * @param jg Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void beforeObjectEntries(JsonGenerator jg) - throws IOException, JsonGenerationException; -} - diff --git a/src/org/codehaus/jackson/VERSION b/src/org/codehaus/jackson/VERSION deleted file mode 100644 index b2ce1b591e..0000000000 --- a/src/org/codehaus/jackson/VERSION +++ /dev/null @@ -1,795 +0,0 @@ -Version: 1.5.4 - -Release date: - 25-Jun-2010 - -Description: - Fourth patch release for 1.5 - - Fixes: - - * [JACKSON-296]: Add support for JAXB/@XmlElementRef(s), fix related - issues uncovered (wrt. handling of polymorphic collection fields) - (reported by Ryan H) - * [JACKSON-311]: Problems handling polymorphic type information for - 'untyped' (Object) bean properties, default typing - (reported by Eric S) - ------------------------------------------------------------------------- -== History: == ------------------------------------------------------------------------- - -1.5.3 [31-May-2010] - - Fixes: - - * [JACKSON-285]: Problem with @JsonCreator annotated constructor that - also uses @JsonDeserialize annotations - - Improvements: - - * [JACKSON-284]: Reduce scope of sync block in - SerializerCache.getReadOnlyLookupMap() - * Partial fix for [JACKSON-289]: allow JSON Array with single-character - Strings to be bound to char[] during deserialization - (suggested by Brian O) - -1.5.2 [25-Apr-2010] - - Fixes: - - * [JACKSON-273]: Yet another OSGi issue, "org.codehaus.jackson.map.util" - not exported by mapper module, needed by jax-rs module. - (reported by Lukasz D) - * [JACKSON-281]: JsonGenerator.writeObject() only supports subset of - wrapper types (when not specifying ObjectCodec) - (reported by Aron A) - - (and all fixes from 1.4.x branch up to 1.4.4) - -1.5.1 [09-Apr-2010] - - Fixes: - - * [JACKSON-265]: problems with generic type handling for serialization - (reported by Fabrice D) - * [JACKSON-269]: missing OSGi export by mapper (o.c.j.m.jsontype.impl), - needed by jackson-xc module - (reported by Raymond F) - - (and all fixes from 1.4.x branch up to 1.4.3) - - -1.5.0 [14-Mar-2010] - - Fixes: - - * [JACKSON-246] JAXB property name determination not working correctly. - (reported by Lars C) - - Improvements: - - * [JACKSON-160] Factory Creator methods now handle polymorphic - construction correctly, allowing manual polymorphic deserialization - * [JACKSON-218] Extended support for Joda date/time types like - LocalDate, LocalDateTime and DateMidnight - * [JACKSON-220] @JsonSerialize.using() was not working properly for - non-Bean types (Collections, Maps, wrappers) - * [JACKSON-236] Allow deserialization of timestamps-as-Strings (not - just timestamps as JSON integer numbers). - (requested by Chris C) - * [JACKSON-255] Allow setter override even with incompatible type - (as long as only one setter per class, so there is no ambiguity) - * [JACKSON-256] AnnotationIntrospector.findSerializationInclusion - was not combining values correctly for JAXB annotations. - (reported by John L) - - New features: - - * [JACKSON-91] Polymorphic Type Handling: automatic handling of - polymorphic types, based on annotations (@JsonTypeInfo) and/or - global settings (ObjectMapper.enableDefaultTyping()) - * [JACKSON-175] Add "org.codehaus.jackson.util.TokenBuffer", used for - much more efficient type conversions (and other internal buffering) - * [JACKSON-195] Add methods to ObjectMapper to allow specification of - root object serialization type. - * [JACKSON-221] Add 'ObjectMapper.writeValueAsBytes()' convenience - method to simplify a common usage pattern - * [JACKSON-229] TypeFactory should have methods to construct parametric - types programmatically (TypeFactory.parametricType()) - * [JACKSON-232] Add 'SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION' - to disable inclusion of non-annotated properties with explicit views - (suggested by Andrei V) - * [JACKSON-234] Add support for JSONP, by adding JSONPObject wrapper - that serializes as expected. - * [JACKSON-241] Add a mechanism for adding new "untouchable" types for - JAX-RS JSON provider, to allow excluding types from being handled - (added method "JacksonJsonProvider.addUntouchable()") - * [JACKSON-244] Allow specifying specific minimum visibility levels for - auto-detecting getters, setters, fields and creators - (requested by Pierre-Yves R) - * [JACKSON-245] Add configuration setting in JAX-RS provider to allow - automatic JSONP wrapping (provider.setJSONPFunctionName()) - * [JACKSON-259] Add JsonParser.Feature to allow disabling field name - canonicalization (JsonParser.Feature.CANONICALIZE_FIELD_NAMES) - - Backwards incompatible changes: - - * Moved following serializers out of BasicSerializerFactory - JdkSerializers: ClassSerializer (into JdkSerializers), - NullSerializer (separate class) - * Add one parameter to StdDeserializer.handleUnknownProperty: - addition was required for handling polymorphic cases that - can use nested JsonParser instances. - * Fixed issues in generic type handling (was not resolving all named - types completely) - * Annotation changes: - * Moved "NoClass" into "org.codehaus.jackson.map.annotate" package - * Removed @JsonUseSerializer and @JsonUseDeserializer annotations - (which has been deprecated for 1.1; replaced by - @JsonSerialize.using and @JsonDeserialize.using, respectively) - * @JsonGetter and @JsonSetter are marked as deprecated, since - @JsonProperty can (and should) be used instead. - -1.4.4 [25-Apr-2010] - - Fixes: - - * [JACKSON-263] BooleanNode.asToken() incorrectly returns 'true' token - for all nodes (not just 'false' ones) - (reported by Gennadiy S) - * [JACKSON-266] Deserialization issues when binding data from JsonNode - (reported by Martin T) - -1.4.3 [18-Feb-2010] - - Fixes: - - * [JACKSON-237]: NPE in deserialization due to race condition - (reported by Benjamin D) - - -1.4.2 [31-Jan-2010] - - Fixes: - - * [JACKSON-238]: Fix to ensure custom serializers can override - default serializers (like DOM, Joda serializers) - (reported by Pablo L) - * other fixes from 1.3.4 release - -1.4.1 [10-Jan-2010] - - Fixes: - - fixes from 1.3.x branch up to 1.3.3. - -1.4.0 [19-Dec-2009] - - Improvements: - - * [JACKSON-38] Allow serializing/deserializing DOM trees (Node, Document) - (suggested by Scott D) - * [JACKSON-89] Make ignored field/creator-backed properties quietly - skippable during deserialization (that is, without having to explicitly - declare such properties as ignorable as per [JACKSON-77]) - * [JACKSON-161] Added basic support for Joda, ser/deser DateTime class - * [JACKSON-170] Serialize Creator properties before other properties - * [JACKSON-196] Schema generation does not respect the annotation - configured serializer on a bean property - (reported by Gil M) - * [JACKSON-208] Add feature (JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS) - to allow unquoted control characters (esp. tabs) in Strings and - field names - (requested by Mark S) - * [JACKSON-216] Jackson JAXB annotation handler does not use @XmlElement.type - property for figuring out actual type - (reported by Mike R) - - New features: - - * [JACKSON-77] Add class annotation @JsonIgnoreProperties to allow - for ignoring specific set of properties for serialization/deserialization - * [JACKSON-90] Added @JsonPropertyOrder, which allows for specifying - order in which properties are serialized. - * [JACKSON-138] Implement JsonView; ability to suppress subsets of - properties, based on view definition. Views are defined using @JsonView - annotation. - * [JACKSON-191] Add access to basic statistics on number of cached - serializers, deserializers (and methods to flush these caches) - * [JACKSON-192] Added basic delegate implementations (JsonParserDelegate, - JsonGeneratorDelegate) to make it easier to override core parser and - generate behavior - * [JACKSON-201] Allow serialization of "empty beans" (classes without - getters), if SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS is - disabled; or if class has recognized Jackson annotation - (suggested by Mike P) - - Other: - - * Removed "BasicSerializerFactory.StringLikeSerializer" that was - deprecated for 1.0, replaced by public "ToStringSerializer" - -1.3.4 [31-Jan-2010] - - Fixes: - - * [JACKSON-225], [JACKSON-227], missing null checks/conversions when - adding entries to ArrayNode and ObjectNode - (reported by Kenny M) - * [JACKSON-230]: wrong NumberType reported for big ints, longs - (reported by Henning S) - * [JACKSON-231]: ArrayDeserializer for byte[] should be able to - use VALUE_EMBEDDED_OBJECT (if Object is byte[]) - -1.3.3 [21-Dec-2009] - - Fixes: - - * [JACKSON-214] Enum types with sub-classes failed to serialize - (reported by Elliot S) - * [JACKSON-215] Add JAX-RS provider annotations on JacksonJaxbJsonProvider - (suggested by Matthew R) - * [JACKSON-220] JsonSerialize.using() not recognized for Collection and - Map types (and similarly for JsonDeserialize) - -1.3.2 [02-Dec-2009] - - Fixes: - - * [JACKSON-103] (additional work) Groovy setMetaClass() setter caused - problems when deserializing (although serialization was fixed earlier) - (reported by Stephen F) - * [JACKSON-187] Issues with GAE security model, Class.getEnclosingMethod() - * [JACKSON-188] Jackson not working on Google App Engine (GAE) due to - unintended dependency from JacksonJsonProvider to JAXB API classes - (reported by Jeff S) - * [JACKSON-206] Support parsing dates of form "1984-11-13T00:00:00" - -1.3.1 [23-Nov-2009] - - Fixes: - - * [JACKSON-190] Problems deserializing certain nested generic types - (reported by Nathan C) - * [JACKSON-194] ObjectMapper class loading issues on Android - (reported by Martin L) - * [JACKSON-197] Remove 2 debug messages that print out to System.err - (reported by Edward T) - * [JACKSON-200] java.sql.Date deserialization not working well - (reported by Steve L) - * [JACKSON-202] Non-public fields not deserialized properly with - JAXB annotations - (reported by Mike P) - * [JACKSON-203] Date deserializers should map empty String to null - (reported by Steve L) - -1.3.0 [30-Oct-2009] - - Fixes: - - * [JACKSON-150] Some JAXB-required core types (XMLGregorianCalendar, - Duration, QName, DataHandler) were not completely supported - * [JACKSON-155] Failed to serialize java.io.File (with infinite - recursion) - (reported by Gabe S) - * [JACKSON-167] Map and Collection sub-classes seem to lose generic - information for deserialization - * [JACKSON-177] Problems with Hibernate, repackaged cglib - (reported by Ted B) - * [JACKSON-179] Single-long-arg factory Creators were not working - (reported by Brian M) - * [JACKSON-183] Root-level 'JsonDeserialize' annotation was not handled - completely; 'as' setting was not taking effect - (reported by Nick P) - - Improvements: - - * [JACKSON-152] Add "ObjectMapper.writeValueAsString()" convenience - method to simplify serializing JSON into String. - * [JACKSON-153] Allow use of @JsonCreator with Map types too - * [JACKSON-158] Bean serializer now checks for direct self-references - (partial, trivial cycle detection) - * [JACKSON-164] Improve null handling for JsonGenerator.writeStringValue - (suggested by Benjamin Darfler) - * [JACKSON-165] Add JsonParser.getBooleanValue() convenience method - (suggested by Benjamin Darfler) - * [JACKSON-166] Add ability to control auto-detection of - "is getters" (boolean isXxx()) methods separate from regular getters - * [JACKSON-168] Make JsonLocation serializable (and deserializable) - (suggested by Shay B) - * [JACKSON-182] Improved handling of SerializationConfig.AUTO_DETECT_GETTERS - with JAXB annotations (uses Jackson-specified default, not JAXB defaults) - - New features: - - * [JACKSON-129] Allow constructing JsonParser to read from JsonNode - (tree representation) - * [JACKSON-154] Added JsonDeserialize.keyUsing and .contentUsing, - to allow for overriding key and content/value deserializers for - properties of structured (array, Collection, Map) types - * [JACKSON-159] Added 'org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider' - to improve use of Jackson as JSON converter for JAX-RS services. - * [JACKSON-173] Add "JsonParser.Feature.ALLOW_SINGLE_QUOTES" to - handle some more invalid JSON content - (requested by Brian M) - * [JACKSON-174] Add "ObjectMapper.convertValue()" convenience method - for simple Object-to-Object conversions, using Jackson's data binding - functionality - * [JACKSON-176] Added 'JsonGenerator.Feature.WRITE_NUMBER_AS_STRINGS' - as a work-around for Javascript problems with big longs (due to - always representing numbers as 64-bit doubles internally) - (requested by Doug D) - * [JACKSON-180] Added 'JsonParser.Feature.INTERN_FIELD_NAMES' to allow - disabling field name intern()ing. - (suggested by Jeff Y) - * [JACKSON-181] Added convenience methods in TypeFactory to allow - dynamically constructed fully typed structured types (map, collection - array types), similar to using TypeReference but without inner classes - * Added method in AnnotationIntrospector to find declared namespace - for JAXB annotations, needed for XML compatibility (future features) - - Other: - - * Removed obsolete class 'org.codehaus.jackson.map.type.TypeReference' - (obsoleted by 'org.codehaus.jackson.type.TypeReference) -- was supposed - to have been removed by 1.0 but had not been. - * Added support to handle 'java.util.regex.Pattern' - -1.2.1 [03-Oct-2009] - - Problems fixed: - - * [JACKSON-162] OSGi packaging problems for xc package. - (reported by Troy Waldrep) - * [JACKSON-171] Self-referential types cause infinite recursion when - using only JAXB annotation introspector - (reported by Randy L) - -1.2.0 [02-Aug-2009] - - Improvements: - - * Added "-use" flag for generating javadocs - (suggested by Dain S) - * [JACKSON-136] JsonParser and JsonGenerator should implement - java.io.Closeable (since they already have close() method) - (suggested by Dain S) - * [JACKSON-148] Changed configuration methods to allow chaining, - by returning 'this' (instead of 'void') - - New features: - - * [JACKSON-33] Allow use of "non-default constructors" and - multiple-argument factory methods for constructing beans to - deserialize - * [JACKSON-69] Support parsing non-standard JSON where Object keys are not quoted - * [JACKSON-76] Mix-in annotations: allow dynamic attachment of - annotations to existing classes, for purposes of configuring - serialization/deserialization behavior - * [JACKSON-92] Allow use of @JsonCreator for constructors and - static methods that take a single deserializable type as argument - (so-called delegating creators) - * [JACKSON-114] Add feature and annotations to make serialization use - static (declared) type over concrete (actual/runtime) type - * [JACKSON-131] Allow constructing and passing of non-shared - SerializationConfig/DeserializationConfig instances to ObjectMapper - * [JACKSON-135] Add basic JsonNode construction support in ObjectMapper - * [JACKSON-147] Add global deserialization feature for suppressing error - reporting for unknown properties - * [JACKSON-149] Add ser/deser features - (DeserializationConfig.Feature.USE_ANNOTATIONS, - SerializationConfig.Feature.USE_ANNOTATIONS) to allow disabling - use of annotations for serialization and/or deserialization config - -1.1.2 [31-Jul-2009] - - Fixes: - - * [JACKSON-143] NPE on ArrayNode.equals() when comparing empty array - node to non-empty array node - (reported by Gregory G) - * [JACKSON-144] Static "getter-like" methods mistaken for getters (for - serialization) - (reported by Dan S) - -1.1.1 [18-Jul-2009] - - Fixes: - - * [JACKSON-139] Non-numeric double values (NaN, Infinity) are serialized - as invalid JSON tokens - (reported by Peter H) - * Core jar incorrectly included much of "mapper" classes (in addition - to core classes) - * Now compiles again using JDK 1.5 javac (1.1.0 didn't) - -1.1.0 [22-Jun-2009] - - Fixes: - - * [JACKSON-109] Allow deserializing into generics Bean classes - (like Wrapper) not just generic Maps and Collections - * [JACKSON-121] Problems deserializing Date values of some ISO-8601 - variants (like one using 'Z' to indicate GMT timezone) - * [JACKSON-122] Annotated serializers and deserializers had to - be public classes with public default constructor; not any more. - - Improvements: - - * [JACKSON-111] Added "jackson-xc" jar to contains XML Compatibility - extensions. - - New features: - - * [JACKSON-70] Add support for generating JSON Schema - * [JACKSON-98] Allow serializing/deserializing field-accessible properties, - in addition to method-accessible ones. - * [JACKSON-105] Allow suppressing output of "default values"; which - means value of a property when bean is constructed using the default - no-arg constructor - (requested by Christoph S) - * [JACKSON-119] Add (optional) support for using JAXB annotations - (by using JaxbAnnotationIntrospector) - (requested by Ryan H) - * [JACKSON-120] Add annotations @JsonSerialize, @JsonDeserialize, - to streamline annotation by replacing host of existing annotations. - * [JACKSON-123] Add "chaining" AnnotationIntrospector (implemented - as inner class, AnnotationIntrospector.Pair) that allows combining - functionality of 2 introspectors. - -1.0.1 [04-Jun-2009] - - Fixes: - - * [JACKSON-104] Build fails on JDK 1.5, assorted other minor issues - (reported by Oleksander A) - * [JACKSON-121] Problems deserializing Date values of some ISO-8601 - variants (like one using 'Z' to indicate GMT timezone) - -1.0.0 [09-May-2009] - - Fixes: - - * [JACKSON-103] Serializing Groovy objects; need to exclude getter method - "getMetaClass" from serialization to prevent infinite recursion - (reported by Ray T) - - Improvements: - - * Removed JAX-RS META-INF/services - based auto-registration for - JAX-RS MessageBodyReader/MessageBodyWriter, because it could - conflict with other application/json content handlers. - -0.9.9-6 [27-Apr-2009] - - Improvements: - - * Improved jax-rs provider integration with jersey; now properly - auto-registers as handler for json media type(s), and allows - for defining custom ObjectMapper to be injected. - -0.9.9-5 [20-Apr-2009] - - New features: - - * [JACKSON-88]: Support for "Setter-less" collection (and Map) types - - Improvements: - - * [JACKSON-100]: Allow specifying that BigInteger should be used instead - of Integer or Long for "generic" integral numeric types (Object, Number) - (DeserializationConfig.Feature.USE_BIG_INTEGER_FOR_INTS) - * [JACKSON-101]: Allow disabling of access modifier overrides - (SerializationgConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS) - to support more security-constrainted running environments. - -0.9.9-4 [14-Apr-2009] - - Fixes: - - * [JACKSON-94] Added missing "JsonParser.readValueAsTree()" method. - * JacksonJsonProvider was using strict equality comparison against - JSON type; instead needs to use "isCompatible". There were other - similar problems - (reported by Stephen D) - * [JACKSON-97] Generic types (with bound wildcards) caused problems - when Class introspector could not figure out that a concrete method - was overriding/implementing generic method; as well as having - problems with synthetic bridge methods. - - Improvements: - - * [JACKSON-95] Added support for deserializing simple exceptions - (Throwable and its sub-classes): anything with a String constructor - (assumed to take "message") should work to some degree. - * [JACKSON-99] IOExceptions should not be wrapped during object - mapping. - (reported by Eldar A) - - New features: - - * [JACKSON-85]: Make Date deserialization (more) configurable (add - DeserializationConfig.setDateFormat()) - * [JACKSON-93]: Allow overriding the default ClassIntrospector. - * [JACKSON-96]: Allow enabling pretty-printing with data binding, - through SerializationConfig object. - -0.9.9-3 [03-Apr-2009] - - Fixes: - - * [JACKSON-79]: Primitive value deserialization fragile wrt nulls - * [JACKSON-81]: Data binding code could lead to unnecessary blocking - because it tried to advance parser (and stream) after binding - (reported by Eldar A) - - New features: - - * [JACKSON-61]: Allow suppressing writing of bean properties with null values - (requested by Justin F) - * [JACKSON-63]: Create CustomDeserializerFactory to allow for adding - custom deserializers for non-structured/generic types. - * [JACKSON-75]: Add "any setter" method; ability to catch otherwise - unknown (unmapped) properties and call a method with name+value. - * [JACKSON-80]: Add @JsonValue annotation, to specify that a Bean value - is to be serialized as value returned by annotated method: can for - example annotate "toString()" method. - * [JACKSON-84]: Added JsonGenerator.writeRawValue methods to augment - existing JsonGenerator.writeRaw() method - (requested by Scott A) - * [JACKSON-86]: Added JsonParser.isClosed() and JsonGenerator.isClosed() - methods. - * [JACKSON-87]: Added ability to customized Date/Calendar serialization, - both by toggling between timestamp (number) and textual (ISO-8601), - and by specifying alternate DateFormat to use. - -0.9.9-2 [19-Mar-2009]: - - Fixes: - - * [JACKSON-75]: Didn't have Deserializer for Number.class. - - Improvements: - - * [JACKSON-68]: Add DeserializationProblemListener, and - DeserializationConfig.addHandler to add instances to ObjectMapper. - * [JACKSON-71]: Add support ser/deser of Class.class. - * [JACKSON-72]: Allow specifying that BigDecimal should be used instead - of Double for "generic" numeric types (Object, Number) - (DeserializationConfig.Feature.USE_BIG_DECIMAL_FOR_FLOATS) - * [JACKSON-73]: Refactored ser/deser configuration settings into - separate configuration classes. - * [JACKSON-78]: Should be able to deserialize ints into Booleans (0 == false) - - New features: - - * [JACKSON-45]: Add convenience methods to help writing custom - serializers - (requested by Scott A) - -0.9.9 [02-Mar-2009]: - - Fixes: - - * [JACKSON-59]: NPE with String[] serializer - (reported by Kevin G) - * [JACKSON-62]: NPE with JsonMappingException if source exception used - null message. - (reported by Justin F) - * [JACKSON-64]: Handling of property name (with @JsonGetter, @JsonSetter) - made bit more intuitive; uses bean naming convention if no explicit - name given. - - Improvements: - - * [JACKSON-60]: Method annotations did not follow intuitive expectations - of inheritability; now do. - * [JACKSON-65]: Need to support typing using "java.lang.reflect.Type", to - help integration with frameworks. - * [JACKSON-66]: ObjectMapper now has "canSerialize" and "canDeserialize" - methods to help frameworks figure out what is supported. - - New features: - - * [JACKSON-52]: Allow disabling name-based auto-detection of - getter methods - (requested by Justin F) - * [JACKSON-58]: Allow defining custom global Enum serializer - (to, for example, make Enums be serialized using Enum.toString(), - or lower-case name or such) - * [JACKSON-67]: Add JAX-RS provider based on Jackson that can handle - JSON content type; initially as a separate jar. - - Other: - - * [JACKSON-22]: all contributors now have submitted contributor - agreement, stored under 'DEV/agreements-received' in svn trunk. - -0.9.8 [18-Feb-2009]: - - Fixes: - - * [JACKSON-49]: Incorrect bounds check for Float values resulted in - exception when trying to serializer 0.0f. - - New features: - - * [JACKSON-32]: add annotations to configure serialization process - (@JsonClass/@JsonContentClass/@JsonKeyClass; @JsonUseSerializer, - @JsonUseDeserializer, @JsonIgnore) - * [JACKSON-36]: add annotations to define property names that differ - from bean naming convention (@JsonGetter/@JsonSetter) - - Improvements: - - * [JACKSON-47]: Change DeserializerProvider.findValueDeserializer to - take "referrer" information. This is needed to be able to give - contextual mappings where a given type may be deserialized differently - (by different deserializer, and possibly to a different java class) - depending on where the reference is from. - * [JACKSON-48]: Integrate ObjectMapper with JsonGenerator, JsonParser; - add MappingJsonFactory. - (suggested by Scott A) - * [JACKSON-50]: JsonNode.getElements() and .iterator() now work for - ObjectNodes too, not just ArrayNodes. Also added convenience factory - methods to allow constructing child nodes directly from container - nodes. - * [JACKSON-53]: iBatis proxied value classes didn't work; fixed by - prevent CGLib-generated "getCallbacks" from getting called. - (reportd by Justin F) - * [JACKSON-55]: Added support for reference-path-tracking in - JsonMappingException, made serializers populate it: this to make - it easier to trouble-shoot nested serialization problems - * [JACKSON-56]: Added support for RFC-1123 date format, along with - simpler "standard" format; and can add more as need be. - -0.9.7 [04-Feb-2009]: - - Improvements: - - * [JACKSON-34]: Improved packaging by adding an intermediate directory - in source tarball, to not mess up the current directory (and to indicate - version number as well) - * [JACKSON-37]: Make Jackson run on Android, by ensuring that there are - no hard linkages to classes that Android SDK doesn't have (the only - reference that was there, to XMLGregorianCalendar, was changed to - soft linkage) - * [JACKSON-42]: Add new JsonNode sub-class, BinaryNode, to represent - base64 encoded binary content. - - New features: - - * [JACKSON-6]: Implement JsonParser.getBinaryValue() so that one can - now also read Base64-encoded binary, not just write. - * [JACKSON-40]: Add JsonParser.nextValue() for more convenient - iteration. - * [JACKSON-46]: Allow disabling quoting of field names by disabling - feature 'JsonGenerator.feature.QUOTE_FIELD_NAMES' - (requested by Scott Anderson) - -0.9.6 [14-Jan-2009]: - - Bug fixes: - - * Serialization of some core types (boolean/java.lang.Boolean, - long/java.lang.Long) was not working due to incorrectly mapped - serializers. - - New features: - - * [JACKSON-31]: Complete rewrite of ObjectMapper's deserialization: - now supports Beans, typed (generics-aware) Lists/Maps/arrays. - - Improvements: - - * [JACKSON-24]: Add efficient byte-array - based parser factory - method to JsonFactory (has maybe 5% improvement over wrapping - in ByteArrayInputStream). - * [JACKSON-29]: Split classes in 2 jars: core that has parser and - generator APIs and implementations; and mapper jar that has object - and tree mapper code. - * [JACKSON-30]: Renamed "JavaTypeMapper" as "ObjectMapper", and - "JsonTypeMapper" as "TreeMapper"; new names should be more intuitive - to indicate their purpose. Will leave simple implementations of - old classes to allow for gradual migration of existing code. - -0.9.5 [10-Dec-2008]: - - Bug fixes: - - * [JACKSON-25]: Problems with Maven pom for lgpl version - (report by Ray R) - note: backported to 0.9.4 Codehaus Maven repo - - Improvements: - - * [JACKSON-13]: JavaTypeMapper can now take JsonFactory argument, and - thus is able to construct JsonParser/JsonGenerator instances as necessary - * [JACKSON-17]: Handling of unknown types now configurable with - JavaTypeMapper serialization (see JsonSerializerProvider for methods) - * [JACKSON-20]: Handling of nulls (key, value) configurable with - JavaTypeMapper serialization (see JsonSerializerProvider for methods) - * [JACKSON-26]: Add convenience JsonGenerator.writeXxxField() methods - to simplify json generation. - - New features: - - * [JACKSON-27]: Allow automatic closing of incomplete START_ARRAY and - START_OBJECT events, when JsonGenerator.close() is called. - -0.9.4 [26-Nov-2008]: - - Bug fixes: - - * [JACKSON-16]: JavaDocs regarding whether Jackson is to close underlying - streams, readers and writers, were incorrect. Additionally added - parser/generator features to allow specifying whether automatic closing - is to be done by Jackson: feature is enabled by default, both for - backwards compatibility, and because it seems like the right setting. - * [JACKSON-18]: ArrayIndexOutOfBounds on IntNode, due to off-by-one - problem with comparisons - (reported by Michael D) - * Fixed a problem with CR (\r) handling; was sometimes skipping - characters (problematic if there's no indentation). - * Multiple UTF-8 decoding fixes: was specifically not working for - names. - - Improvements: - - * More complete JavaDoc comments for core public classes. - * Internal cleanup of core parsing, to unify handling of Object and - Array entries - -0.8.0 - 0.9.3 [between 17-Oct-2007 and 05-Sep-2008]: - - Changes: - - * [JACKSON-5]: Symbol table construction was not thread-safe for - utf-8 encoded content (new bug with 0.9.2, not present with earlier) - (reported by Tudor B) - * [JACKSON-8]: Serialization of BigDecimal broken with JavaTypeMapper - (reported by Johannes L) - * [JACKSON-9]: Add support for (non-standard) Json comments. - (requested by Mike G) - * [JACKSON-11]: Implement base64/binary methods for json generator. - * [JACKSON-14]: Problems with generic collections, serializer - method signatures (due to lack of covariance wrt collection types) - * [JACKSON-15]: Add copy-through methods to JsonGenerator for - pass-through copying of content (copyCurrentEvent, copyCurrentStructure) - * [JACKSON-23]: Add OSGi manifest headers for jars (to run on OSGi container). - * Added generic "feature" mechanism to parsers, writers; features are - togglable (on/off) things with well-defined default values, implemented - as Enums. - - * [JACKSON-1]: JsonNode now implements Iterable so that - it is possible use Java 5 foreach loop over array/object nodes. - (suggested by Michael M) - * [JACKSON-4] Added JsonParser.skipChildren() method. - * UTF-16/32 handling was not completely correct, was erroneously - skipping first 2/4 bytes in some cases (even when no BOM included). - Also, related unit tests added/fixed. - * JsonGenerator.useDefaultPrettyPrinter()/.setPrettyPrinter() - allow for pretty printing (indentation). - (thanks to Ziad M for suggestion, sample code) - - * Implicit conversions for numbers could sometimes lose accuracy, - if floating-point number was first accessed as int/long, and then - as a BigDecimal. - * One Nasty NPE fixed from NameCanonicalizer (which was added in 0.9.2) - - * Java type mapper had a bug in Collection mapping (mismatched - calls between writeStartArray and writeEndObject!) - (reported by Mike E) - * Java type mapper had a bug which prevented custom mappers (as - well as slower interface-based introspection) from working. - (reported by Mike E) - * Numeric value parsing had some problems - * JavaTypeMapper and JsonTypeMapper had a bug which resulted - in NullPointerException when stream ends, instead of returning - null to indicate it. - (reported by Augusto C) - * JavaTypeMapper did not implicitly flush generator after mapping - objects: it should, and now will (note: JsonTypeMapper not directly - affected, flushing still needed) - (suggested by Maciej P) diff --git a/src/org/codehaus/jackson/annotate/JacksonAnnotation.java b/src/org/codehaus/jackson/annotate/JacksonAnnotation.java deleted file mode 100644 index 25bf61e27a..0000000000 --- a/src/org/codehaus/jackson/annotate/JacksonAnnotation.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Meta-annotation (annotations used on other annotations) - * used for marking all annotations that are - * part of Jackson package. Can be used for recognizing all - * Jackson annotations generically, and in future also for - * passing other generic annotation configuration. - */ -@Target({ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface JacksonAnnotation -{ - // for now, a pure tag annotation, no parameters -} diff --git a/src/org/codehaus/jackson/annotate/JsonAnySetter.java b/src/org/codehaus/jackson/annotate/JsonAnySetter.java deleted file mode 100644 index ba022aa80b..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonAnySetter.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define a non-static, - * single-argument method, to be used as a "fallback" handler - * for all otherwise unrecognized properties found from Json content. - *

- * If used, all otherwise unmapped key-value pairs from Json Object - * structs are added to the property (of type Map or bean). - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonAnySetter -{ -} diff --git a/src/org/codehaus/jackson/annotate/JsonAutoDetect.java b/src/org/codehaus/jackson/annotate/JsonAutoDetect.java deleted file mode 100644 index 48627d532d..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonAutoDetect.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Member; -import java.lang.reflect.Modifier; - -/** - * Class annotation that can be used to define which kinds of Methods - * are to be detected by auto-detection. - * Auto-detection means using name conventions - * and/or signature templates to find methods to use for data binding. - * For example, so-called "getters" can be auto-detected by looking for - * public member methods that return a value, do not take argument, - * and have prefix "get" in their name. - *

- * Pseudo-value NONE means that all auto-detection is disabled - * for the specific class that annotation is applied to (including - * its super-types, but only when resolving that class). - * Pseudo-value ALWAYS means that auto-detection is enabled - * for all method types for the class in similar way. - *

- * The default value is ALWAYS: that is, by default, auto-detection - * is enabled for all classes unless instructed otherwise. - *

- * Starting with version 1.5, it is also possible to use more fine-grained - * definitions, to basically define minimum visibility level needed. Defaults - * are different for different types (getters need to be public; setters can - * have any access modifier, for example). - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonAutoDetect -{ - /** - * Enumeration for possible visibility thresholds (minimum visibility) - * that can be used to limit which methods (and fields) are - * auto-detected. - * - * @since 1.5 - */ - public enum Visibility { - /** - * Value that means that all kinds of access modifiers are acceptable, - * from private to public. - */ - ANY, - /** - * Value that means that any other access modifier other than 'private' - * is considered auto-detectable. - */ - NON_PRIVATE, - /** - * Value that means access modifiers 'protected' and 'public' are - * auto-detectable (and 'private' and "package access" == no modifiers - * are not) - */ - PROTECTED_AND_PUBLIC, - /** - * Value to indicate that only 'public' access modifier is considered - * auto-detectable. - */ - PUBLIC_ONLY, - /** - * Value that indicates that no access modifiers are auto-detectable: - * this can be used to explicitly disable auto-detection for specified - * types. - */ - NONE, - - /** - * Value that indicates that default visibility level (whatever it is, - * depends on context) is to be used. This usually means that inherited - * value (from parent visibility settings) is to be used. - */ - DEFAULT; - - public boolean isVisible(Member m) { - switch (this) { - case ANY: - return true; - case NONE: - return false; - case NON_PRIVATE: - return !Modifier.isPrivate(m.getModifiers()); - case PROTECTED_AND_PUBLIC: - if (Modifier.isProtected(m.getModifiers())) { - return true; - } - // fall through to public case: - case PUBLIC_ONLY: - return Modifier.isPublic(m.getModifiers()); - } - return false; - } - } - - /** - * Types of property elements (getters, setters, fields, creators) that can - * be auto-detected.NOTE: as of 1.5, it is recommended that instead of - * defining this property, distinct visibility properties are used instead. - * This because levels used with this method are not explicit, but global - * defaults that differ for different methods. As such, this property can be - * considered deprecated and only retained for backwards - * compatibility. - * - * @return Undocumented - */ - JsonMethod[] value() default { JsonMethod.ALL }; - - /** - * Minimum visibility required for auto-detecting regular getter methods. - * - * @return Undocumented - * @since 1.5 - */ - Visibility getterVisibility() default Visibility.DEFAULT; - - /** - * Minimum visibility required for auto-detecting is-getter methods. - * - * @return Undocumented - * @since 1.5 - */ - Visibility isGetterVisibility() default Visibility.DEFAULT; - - /** - * Minimum visibility required for auto-detecting setter methods. - * - * @return Undocumented - * @since 1.5 - */ - Visibility setterVisibility() default Visibility.DEFAULT; - - /** - * Minimum visibility required for auto-detecting Creator methods, - * except for no-argument constructors (which are always detected - * no matter what). - * - * @return Undocumented - * @since 1.5 - */ - Visibility creatorVisibility() default Visibility.DEFAULT; - - /** - * Minimum visibility required for auto-detecting member fields. - * - * @return Undocumented - * @since 1.5 - */ - Visibility fieldVisibility() default Visibility.DEFAULT; -} diff --git a/src/org/codehaus/jackson/annotate/JsonClass.java b/src/org/codehaus/jackson/annotate/JsonClass.java deleted file mode 100644 index d6be7a2f80..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonClass.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used with "setter" methods to - * indicate the actual type to use for deserializing value - * of the associated logical property. - * This is usually done if the declared type is abstract or too generic; - * annotation can denote actual concrete type to instantiate when - * deserializing the property. - *

- * The indicated type must be compatible with the declared - * type. For deserialization (setters) this means that - * it has to be a sub-type or implementation of - * the declared type. - * If this constraint is violated, an exception (usually - * {@link IllegalArgumentException}) can be thrown by runtime. - *

- * Note that for container types (arrays, Lists/Collections/Maps) this - * indicates the type of container itself; for contained Objects, use - * {@link JsonContentClass} instead (or for Map keys, - * {@link JsonKeyClass}). - * - * @deprecated - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -@Deprecated -public @interface JsonClass -{ - /** - * Class that is the type to use for deserializating value of - * the property associated - * with the annotated method. - * @return Undocumented - */ - public Class value(); -} diff --git a/src/org/codehaus/jackson/annotate/JsonContentClass.java b/src/org/codehaus/jackson/annotate/JsonContentClass.java deleted file mode 100644 index 3f0d5d789c..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonContentClass.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used to mark "setter" methods to indicate the - * actual type of values contained in a container type that is value - * of the property associated with the method. - * (phew! that's a mouthful!). - * This is usually done if the declared element type is abstract or - * too generic; annotation can denote actual concrete type to - * instantiate when deserializing contents of the container. - * To define type of the actual container itself, use - * {@link JsonClass} instead. - *

- * Note that the indicated type must be compatible with the declared - * type; that is, it has to be a sub-type or implementation of - * the declared type. This is usually the case; and if it wasn't - * then the call to associated "setter" method would fail with - * a type-mismatch exception. - * - * @deprecated - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -@Deprecated -public @interface JsonContentClass -{ - /** - * Class that is the expected concrete value type of the container - * (which is value of the property associated - * with the annotated method). Will be used by deserializer to - * instantiate the type, using - *

- * Note: if a non-property method is annotated with this annotation, - * deserializer will throw an exception to denote invalid annotation. - * @return Undocumented - */ - public Class value(); -} diff --git a/src/org/codehaus/jackson/annotate/JsonCreator.java b/src/org/codehaus/jackson/annotate/JsonCreator.java deleted file mode 100644 index 72feac8b7f..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonCreator.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define constructors and factory - * methods as one to use for instantiating new instances of the associated - * class. - */ -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonCreator -{ - // no values, since there's no property -} diff --git a/src/org/codehaus/jackson/annotate/JsonGetter.java b/src/org/codehaus/jackson/annotate/JsonGetter.java deleted file mode 100644 index efe8942757..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonGetter.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define a non-static, - * no-argument value-returning (non-void) method to be used as a "getter" - * for a logical property, - * as an alternative to recommended - * {@link JsonProperty} annotation (which was introduced in version 1.1). - *

- * Getter means that when serializing Object instance of class that has - * this method (possibly inherited from a super class), a call is made - * through the method, and return value will be serialized as value of - * the property. - * - * @deprecated Use {@link JsonProperty} instead (deprecated since version 1.5) - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -@Deprecated -public @interface JsonGetter -{ - /** - * Defines name of the logical property this - * method is used to access ("get"); empty String means that - * name should be derived from the underlying method (using - * standard Bean name detection rules) - * @return Undocumented - */ - String value() default ""; -} diff --git a/src/org/codehaus/jackson/annotate/JsonIgnore.java b/src/org/codehaus/jackson/annotate/JsonIgnore.java deleted file mode 100644 index 777fce1301..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonIgnore.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation -* that indicates that the annotated method or field is to be ignored by -* introspection-based - * serialization and deserialization functionality. That is, it should - * not be consider a "getter", "setter" or "creator". - *

- * For example, - * a "getter" method that would otherwise denote - * a property (like, say, "getValue" to suggest property "value") - * to serialize, would be ignored and no such property would - * be output unless another annotation defines alternative method - * to use. - *

- * This annotation works purely on method-by-method (or field-by-field) basis; - * annotation on one method or field does not imply ignoring other methods - * or fields. - * Specifically, marking a "setter" candidate does not change handling - * of matching "getter" method (or vice versa). - *

- * Annotation is usually used just a like a marker annotation, that - * is, without explicitly defining 'value' argument (which defaults - * to true): but argument can be explicitly defined. - * This can be done to override an existing JsonIgnore by explictly - * defining one with 'false' argument. - */ -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonIgnore -{ - /** - * Optional argument that defines whether this annotation is active - * or not. The only use for value 'false' if for overriding purposes - * (which is not needed often); most likely it is needed for use - * with "mix-in annotations" (aka "annotation overrides"). - * For most cases, however, default value of "true" is just fine - * and should be omitted. - * @return Undocumented - */ - boolean value() default true; -} diff --git a/src/org/codehaus/jackson/annotate/JsonIgnoreProperties.java b/src/org/codehaus/jackson/annotate/JsonIgnoreProperties.java deleted file mode 100644 index 1e192b8b68..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonIgnoreProperties.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used to either suppress serialization of - * properties (during serialization), or ignore processing of - * JSON properties read (during deserialization). - *

- * Example: - *

- * // to prevent specified fields from being serialized or deserialized
- * // (i.e. not include in JSON output; or being set even if they were included)
- * \@JsonIgnoreProperties({ "internalId", "secretKey" })
- * // To ignore any unknown properties in JSON input without exception:
- * \@JsonIgnoreProperties(ignoreUnknown=true)
- *
- *

- * Only applicable to classes, not for properties (getters, setters, fields). - * - * @since 1.4 - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonIgnoreProperties -{ - /** - * Names of properties to ignore. - * @return Undocumented - */ - public String[] value() default { }; - - /** - * Property that defines whether it is ok to just ignore any - * unrecognized properties during deserialization. - * If true, all properties that are unrecognized -- that is, - * there are no setters or creators that accept them -- are - * ignored without warnings (although handlers for unknown - * properties, if any, will still be called) without - * exception. - *

- * Does not have any effect on serialization. - * @return Undocumented - */ - public boolean ignoreUnknown() default false; -} diff --git a/src/org/codehaus/jackson/annotate/JsonKeyClass.java b/src/org/codehaus/jackson/annotate/JsonKeyClass.java deleted file mode 100644 index 9de10398f3..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonKeyClass.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used to mark "setter" methods to indicate the - * actual type of key Objects for the Map type that is value - * of the property associated with the method. - * This is usually done if the declared element type is abstract or - * too generic; annotation can denote actual concrete type to - * instantiate when deserializing contents of the container. - * To define type of the actual container itself, use - * {@link JsonClass} instead. - *

- * Note that the indicated type must be compatible with the declared - * type; that is, it has to be a sub-type or implementation of - * the declared type. This is usually the case; and if it wasn't - * then the call to associated "setter" method would fail with - * a type-mismatch exception. - *

- * Note: while any class can be indicated as the Key class, there - * must be a registered Key Deserializer for the type. - * - * @deprecated - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -@Deprecated -public @interface JsonKeyClass -{ - /** - * Class that is the expected concrete value type of the container - * (which is value of the property associated - * with the annotated method). Will be used by deserializer to - * instantiate the type, using - *

- * Note: if a non-property method is annotated with this annotation, - * deserializer will throw an exception to denote invalid annotation. - * @return Undocumented - */ - public Class value(); -} diff --git a/src/org/codehaus/jackson/annotate/JsonMethod.java b/src/org/codehaus/jackson/annotate/JsonMethod.java deleted file mode 100644 index 2588b1f34d..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonMethod.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.codehaus.jackson.annotate; - -/** - * Enumeration used to define kinds of methods that annotations like - * {@link JsonAutoDetect} apply to. - *

- * In addition to actual method types (GETTER, SETTER, CREATOR; and - * sort-of-method, FIELD), 2 pseudo-types - * are defined for convenience: ALWAYS and NONE. These - * can be used to indicate, all or none of available method types (respectively), - * for use by annotations that takes JsonMethod argument. - */ -public enum JsonMethod -{ - /** - * Getters are methods used to get a POJO field value for serialization, - * or, under certain conditions also for de-serialization. Latter - * can be used for effectively setting Collection or Map values - * in absence of setters, iff returned value is not a copy but - * actual value of the logical property. - *

- * Since version 1.3, this does NOT include "is getters" (methods - * that return boolean and named 'isXxx' for property 'xxx'); instead, - * {@link #IS_GETTER} is used}. - */ - GETTER, - - /** - * Setters are methods used to set a POJO value for deserialization. - */ - SETTER, - - /** - * Creators are constructors and (static) factory methods used to - * construct POJO instances for deserialization - */ - CREATOR, - - /** - * Field refers to fields of regular Java objects. Although - * they are not really methods, addition of optional field-discovery - * in version 1.1 meant that there was need to enable/disable - * their auto-detection, and this is the place to add it in. - * - * @since 1.1 - */ - FIELD, - - /** - * "Is getters" are getter-like methods that are named "isXxx" - * (instead of "getXxx" for getters) and return boolean value - * (either primitive, or {@link java.lang.Boolean}). - * - * @since 1.3 - */ - IS_GETTER, - - /** - * This pseudo-type indicates that none of real types is included - */ - NONE, - - /** - * This pseudo-type indicates that all of real types are included - */ - ALL - ; - - private JsonMethod() { } - - public boolean creatorEnabled() { - return (this == CREATOR) || (this == ALL); - } - - public boolean getterEnabled() { - return (this == GETTER) || (this == ALL); - } - - public boolean isGetterEnabled() { - return (this == IS_GETTER) || (this == ALL); - } - - public boolean setterEnabled() { - return (this == SETTER) || (this == ALL); - } - - public boolean fieldEnabled() { - return (this == FIELD) || (this == ALL); - } -} diff --git a/src/org/codehaus/jackson/annotate/JsonProperty.java b/src/org/codehaus/jackson/annotate/JsonProperty.java deleted file mode 100644 index edd2cc00a1..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonProperty.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define a non-static - * method as a "setter" or "getter" for a logical property - * (depending on its signature), - * or non-static object field to be used (serialized, deserialized) as - * a logical property. - *

- * Default value ("") indicates that the field name is used - * as the property name without any modifications, but it - * can be specified to non-empty value to specify different - * name. Property name refers to name used externally, as - * the field name in Json objects. - *

- * NOTE: since version 1.1, annotation has also been applicable - * to fields (not with 1.0). - *

- * NOTE: since version 1.2, annotation has also been applicable - * to (constructor) parameters - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonProperty -{ - /** - * Defines name of the logical property, i.e. Json object field - * name to use for the property: if empty String (which is the - * default), will use name of the field that is annotated. - * @return Undocumented - */ - String value() default ""; -} diff --git a/src/org/codehaus/jackson/annotate/JsonPropertyOrder.java b/src/org/codehaus/jackson/annotate/JsonPropertyOrder.java deleted file mode 100644 index 866c732448..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonPropertyOrder.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used to define ordering (possibly partial) to use - * when serializing object properties. Properties included in annotation - * declaration will be serialized first (in defined order), followed by - * any properties not included in the definition. - * Annotation definition will override any implicit orderings (such as - * guarantee that Creator-properties are serialized before non-creator - * properties) - *

- * Examples: - *

- *  // ensure that "id" and "name" are output before other properties
- *  \@JsonPropertyOrder({ "id", "name" })
- *  // order any properties that don't have explicit setting using alphabetic order
- *  \@JsonPropertyOrder(alphabetic=true)
- *
- *

- * This annotation has no effect on deserialization. - * - * @since 1.4 - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonPropertyOrder -{ - /** - * Order in which properties of annotated object are to be serialized in. - * @return Undocumented - */ - public String[] value() default { }; - - /** - * Property that defines what to do regarding ordering of properties - * not explicitly included in annotation instance. If set to true, - * they will be alphabetically ordered; if false, order is - * undefined (default setting) - * @return Undocumented - */ - public boolean alphabetic() default false; -} diff --git a/src/org/codehaus/jackson/annotate/JsonSetter.java b/src/org/codehaus/jackson/annotate/JsonSetter.java deleted file mode 100644 index c9cfcff2db..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonSetter.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation that can be used to define a non-static, - * single-argument method to be used as a "setter" for a logical property - * as an alternative to recommended - * {@link JsonProperty} annotation (which was introduced in version 1.1). - *

- * Setter means that when a property with matching name is encountered in - * JSON content, this method will be used to set value of the property. - * - * @deprecated Use {@link JsonProperty} instead (deprecated since version 1.5) - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -@Deprecated -public @interface JsonSetter -{ - /** - * Optional default argument that defines logical property this - * method is used to modify ("set"). - * @return Undocumented - */ - String value() default ""; -} diff --git a/src/org/codehaus/jackson/annotate/JsonSubTypes.java b/src/org/codehaus/jackson/annotate/JsonSubTypes.java deleted file mode 100644 index bacbf61138..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonSubTypes.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation used with {@link JsonTypeInfo} to indicate sub types of serializable - * polymorphic types, and to associate logical names used within JSON content - * (which is more portable than using physical Java class names). - * - * @since 1.5 - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonSubTypes { - /** - * Subtypes of the annotated type (annotated class, or property value type - * associated with the annotated method). These will be checked recursively - * so that types can be defined by only including direct subtypes. - * @return Undocumented - */ - public Type[] value(); - - /** - * Definition of a subtype, along with optional name. If name is missing, class - * of the type will be checked for {@link JsonTypeName} annotation; and if that - * is also missing or empty, a default - * name will be constructed by type id mechanism. - * Default name is usually based on class name. - */ - public @interface Type { - /** - * Class of the subtype - * @return Undocumented - */ - public Class value(); - - /** - * Logical type name used as the type identifier for the class - * @return Undocumented - */ - public String name() default ""; - } -} diff --git a/src/org/codehaus/jackson/annotate/JsonTypeInfo.java b/src/org/codehaus/jackson/annotate/JsonTypeInfo.java deleted file mode 100644 index a0ece10e0d..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonTypeInfo.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation used for configuring details of if and how type information is - * used with JSON serialization and deserialization, to preserve information - * about actual class of Object instances. This is necessarily for polymorphic - * types, and may also be needed to link abstract declared types and matching - * concrete implementation. - *

- * Some examples of typical annotations: - *

- *  // Include Java class name ("com.myempl.ImplClass") as JSON property "class"
- *  \@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="class")
- *  
- *  // Include logical type name (defined in impl classes) as wrapper; 2 annotations
- *  \@JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT)
- *  \@JsonSubTypes({com.myemp.Impl1.class, com.myempl.Impl2.class})
- *
- * @since 1.5 - * - * @author tatu - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonTypeInfo -{ - /* - ******************************************************************* - * Value enumerations used for properties - ******************************************************************* - */ - - /** - * Definition of different type identifiers that can be included in JSON - * during serialization, and used for deserialization. - */ - public enum Id { - /** - * This means that no explicit type metadata is included, and typing is - * purely done using contextual information possibly augmented with other - * annotations. - */ - NONE(null), - - /** - * Means that fully-qualified Java class name is used as the type identifier. - */ - CLASS("@class"), - - /** - * Means that Java class name with minimal path is used as the type identifier. - * Minimal means that only class name, and that part of preceding Java - * package name is included that is needed to construct fully-qualified name - * given fully-qualified name of the declared supertype. - * For example, for supertype "com.foobar.Base", and concrete type - * "com.foo.Impl", only "Impl" would be included; and for "com.foo.impl.Impl2" - * only "impl.Impl2" would be included. - *

- * If all related classes are in the same Java package, this option can reduce - * amount of type information overhead, especially for small types. - * However, please note that using this alternative is inherently risky since it - * assumes that the - * supertype can be reliably detected. Given that it is based on declared type - * (since ultimate supertype, java.lang.Object would not be very - * useful reference point), this may not always work as expected. - */ - MINIMAL_CLASS("@c"), - - /** - * Means that logical type name is used as type information; name will then need - * to be separately resolved to actual concrete type (Class). - */ - NAME("@type"), - - /** - * Means that typing mechanism uses customized handling, with possibly - * custom configuration. This means that semantics of other properties is - * not defined by Jackson package, but by the custom implementation. - */ - CUSTOM(null) - ; - - private final String _defaultPropertyName; - - private Id(String defProp) { - _defaultPropertyName = defProp; - } - - public String getDefaultPropertyName() { return _defaultPropertyName; } - } - - /** - * Definition of standard type inclusion mechanisms for type metadata. - * Used for standard metadata types, except for {@link Id#NONE}. - * May or may not be used for custom types ({@link Id#CUSTOM}). - */ - public enum As { - /** - * Inclusion mechanism that uses a single configurable property, included - * along with actual data (POJO properties) as a separate meta-property. - *

- * Default choice for inclusion. - */ - PROPERTY, - - /** - * Inclusion mechanism that wraps typed JSON value (POJO - * serialized as JSON) in - * a JSON Object that has a single entry, - * where field name is serialized type identifier, - * and value is the actual JSON value. - *

- * Note: can only be used if type information can be serialized as - * String. This is true for standard type metadata types, but not - * necessarily for custom types. - */ - WRAPPER_OBJECT, - - /** - * Inclusion mechanism that wraps typed JSON value (POJO - * serialized as JSON) in - * a 2-element JSON array: first element is the serialized - * type identifier, and second element the serialized POJO - * as JSON Object. - */ - WRAPPER_ARRAY, - ; - } - - /* - ******************************************************************* - * Annotation properties - ******************************************************************* - */ - - /** - * What kind of type metadata is to be used for serializing and deserializing - * type information for instances of annotated type (and its subtypes - * unless overridden) - * @return Undocumented - */ - public Id use(); - - /** - * What mechanism is used for including type metadata (if any; for - * {@link Id#NONE} nothing is included). Default - *

- * Note that for type metadata type of {@link Id#CUSTOM}, - * this setting may or may not have any effect. - * @return Undocumented - */ - public As include() default As.PROPERTY; - - /** - * Property names used when type inclusion method ({@link As#PROPERTY}) is used - * (or possibly when using type metadata of type {@link Id#CUSTOM}). - *

- * Default property name used if this property is not explicitly defined - * (or is set to empty String) is based on - * type metadata type ({@link #use}) used. - * @return Undocumented - */ - public String property() default ""; -} diff --git a/src/org/codehaus/jackson/annotate/JsonTypeName.java b/src/org/codehaus/jackson/annotate/JsonTypeName.java deleted file mode 100644 index e09ed110bb..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonTypeName.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotation used for binding logical name that the annotated class - * has. Used with {@link JsonTypeInfo} (and specifically its - * {@link JsonTypeInfo#use} property) to establish relationship - * between type names and types. - * - * @since 1.5 - * - * @author tatu - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonTypeName { - /** - * Logical type name for annotated type. If missing (or defined as Empty String), - * defaults to using non-qualified class name as the type. - * @return Undocumented - */ - public String value() default ""; -} diff --git a/src/org/codehaus/jackson/annotate/JsonValue.java b/src/org/codehaus/jackson/annotate/JsonValue.java deleted file mode 100644 index d9a5cf6055..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonValue.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marker annotation - * that indicates that results of the annotated "getter" method - * (which means signature must be that of getters; non-void return - * type, no args) is to be used as the single value to serialize - * for the instance. Usually value will be of a simple scalar type - * (String or Number), but it can be any serializable type (Collection, - * Map or Bean). - *

- * At most one method of a Class can be annotated with this annotation; - * if more than one is found, an exception may be thrown. - * Also, if method signature is not compatible with Getters, an exception - * may be thrown. - * Whether exception is thrown or not is an implementation detail (due - * to filtering during introspection, some annotations may be skipped) - * and applications should not rely on specific behavior. - *

- * A typical use case is that of annotating toString() - * method so that returned String value is Object's Json serialization. - *

- * Boolean argument is only used so that sub-classes can "disable" - * annotation if necessary. - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonValue -{ - /** - * Optional argument that defines whether this annotation is active - * or not. The only use for value 'false' if for overriding purposes. - * Overriding may be necessary when used - * with "mix-in annotations" (aka "annotation overrides"). - * For most cases, however, default value of "true" is just fine - * and should be omitted. - * @return Undocumented - */ - boolean value() default true; -} diff --git a/src/org/codehaus/jackson/annotate/JsonWriteNullProperties.java b/src/org/codehaus/jackson/annotate/JsonWriteNullProperties.java deleted file mode 100644 index 78d8c78ba9..0000000000 --- a/src/org/codehaus/jackson/annotate/JsonWriteNullProperties.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.codehaus.jackson.annotate; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that can be used to define whether object properties - * that have null values are to be written out when serializing - * content as JSON. This affects Bean and Map serialization. - *

- * Annotation can be used with Classes (all instances of - * given class) and Methods. - *

- * Default value for this property is 'true', meaning that null - * properties are written. - */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotation -public @interface JsonWriteNullProperties -{ - /** - * Whether properties for beans of annotated type will always be - * written (true), or only if not null (false). - * @return Undocumented - */ - boolean value() default true; -} diff --git a/src/org/codehaus/jackson/impl/ByteSourceBootstrapper.java b/src/org/codehaus/jackson/impl/ByteSourceBootstrapper.java deleted file mode 100644 index 65b61f257f..0000000000 --- a/src/org/codehaus/jackson/impl/ByteSourceBootstrapper.java +++ /dev/null @@ -1,354 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.*; -import org.codehaus.jackson.sym.BytesToNameCanonicalizer; -import org.codehaus.jackson.sym.CharsToNameCanonicalizer; - -/** - * This class is used to determine the encoding of byte stream - * that is to contain JSON content. Rules are fairly simple, and - * defined in JSON specification (RFC-4627 or newer), except - * for BOM handling, which is a property of underlying - * streams. - */ -public final class ByteSourceBootstrapper -{ - /* - /********************************************* - /* Configuration - /********************************************* - */ - - final IOContext _context; - - final InputStream _in; - - /* - /********************************************* - /* Input buffering - /********************************************* - */ - - final byte[] _inputBuffer; - - private int _inputPtr; - - private int _inputEnd; - - /** - * Flag that indicates whether buffer above is to be recycled - * after being used or not. - */ - private final boolean _bufferRecyclable; - - /* - /********************************************* - /* Input location - /********************************************* - */ - - /** - * Current number of input units (bytes or chars) that were processed in - * previous blocks, - * before contents of current input buffer. - *

- * Note: includes possible BOMs, if those were part of the input. - */ - protected int _inputProcessed; - - /* - /********************************************* - /* Data gathered - /********************************************* - */ - - boolean _bigEndian = true; - int _bytesPerChar = 0; // 0 means "dunno yet" - - /* - /********************************************* - /* Life-cycle - /********************************************* - */ - - public ByteSourceBootstrapper(IOContext ctxt, InputStream in) - { - _context = ctxt; - _in = in; - _inputBuffer = ctxt.allocReadIOBuffer(); - _inputEnd = _inputPtr = 0; - _inputProcessed = 0; - _bufferRecyclable = true; - } - - public ByteSourceBootstrapper(IOContext ctxt, byte[] inputBuffer, int inputStart, int inputLen) - { - _context = ctxt; - _in = null; - _inputBuffer = inputBuffer; - _inputPtr = inputStart; - _inputEnd = (inputStart + inputLen); - // Need to offset this for correct location info - _inputProcessed = -inputStart; - _bufferRecyclable = false; - } - - /** - * Method that should be called after constructing an instace.It will figure out encoding that content uses, to - * allow for instantiating a proper scanner object. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - public JsonEncoding detectEncoding() - throws IOException, JsonParseException - { - boolean foundEncoding = false; - - // First things first: BOM handling - /* Note: we can require 4 bytes to be read, since no - * combination of BOM + valid JSON content can have - * shorter length (shortest valid JSON content is single - * digit char, but BOMs are chosen such that combination - * is always at least 4 chars long) - */ - if (ensureLoaded(4)) { - int quad = (_inputBuffer[_inputPtr] << 24) - | ((_inputBuffer[_inputPtr+1] & 0xFF) << 16) - | ((_inputBuffer[_inputPtr+2] & 0xFF) << 8) - | (_inputBuffer[_inputPtr+3] & 0xFF); - - if (handleBOM(quad)) { - foundEncoding = true; - } else { - /* If no BOM, need to auto-detect based on first char; - * this works since it must be 7-bit ascii (wrt. unicode - * compatible encodings, only ones JSON can be transferred - * over) - */ - // UTF-32? - if (checkUTF32(quad)) { - foundEncoding = true; - } else if (checkUTF16(quad >>> 16)) { - foundEncoding = true; - } - } - } else if (ensureLoaded(2)) { - int i16 = ((_inputBuffer[_inputPtr] & 0xFF) << 8) - | (_inputBuffer[_inputPtr+1] & 0xFF); - if (checkUTF16(i16)) { - foundEncoding = true; - } - } - - JsonEncoding enc; - - /* Not found yet? As per specs, this means it must be UTF-8. */ - if (!foundEncoding) { - enc = JsonEncoding.UTF8; - } else if (_bytesPerChar == 2) { - enc = _bigEndian ? JsonEncoding.UTF16_BE : JsonEncoding.UTF16_LE; - } else if (_bytesPerChar == 4) { - enc = _bigEndian ? JsonEncoding.UTF32_BE : JsonEncoding.UTF32_LE; - } else { - throw new RuntimeException("Internal error"); // should never get here - } - _context.setEncoding(enc); - return enc; - } - - public Reader constructReader() - throws IOException - { - JsonEncoding enc = _context.getEncoding(); - switch (enc) { - case UTF32_BE: - case UTF32_LE: - return new UTF32Reader(_context, _in, _inputBuffer, _inputPtr, _inputEnd, - _context.getEncoding().isBigEndian()); - - case UTF16_BE: - case UTF16_LE: - case UTF8: // only in non-common case where we don't want to do direct mapping - { - // First: do we have a Stream? If not, need to create one: - InputStream in = _in; - - if (in == null) { - in = new ByteArrayInputStream(_inputBuffer, _inputPtr, _inputEnd); - } else { - /* Also, if we have any read but unused input (usually true), - * need to merge that input in: - */ - if (_inputPtr < _inputEnd) { - in = new MergedStream(_context, in, _inputBuffer, _inputPtr, _inputEnd); - } - } - return new InputStreamReader(in, enc.getJavaName()); - } - } - throw new RuntimeException("Internal error"); // should never get here - } - - public JsonParser constructParser(int features, ObjectCodec codec, BytesToNameCanonicalizer rootByteSymbols, CharsToNameCanonicalizer rootCharSymbols) - throws IOException, JsonParseException - { - JsonEncoding enc = detectEncoding(); - - // As per [JACKSON-259], may want to fully disable canonicalization: - boolean canonicalize = JsonParser.Feature.CANONICALIZE_FIELD_NAMES.enabledIn(features); - boolean intern = JsonParser.Feature.INTERN_FIELD_NAMES.enabledIn(features); - if (enc == JsonEncoding.UTF8) { - /* and without canonicalization, byte-based approach is not performance; just use std UTF-8 reader - * (which is ok for larger input; not so hot for smaller; but this is not a common case) - */ - if (canonicalize) { - BytesToNameCanonicalizer can = rootByteSymbols.makeChild(canonicalize, intern); - return new Utf8StreamParser(_context, features, _in, codec, can, _inputBuffer, _inputPtr, _inputEnd, _bufferRecyclable); - } - } - return new ReaderBasedParser(_context, features, constructReader(), codec, rootCharSymbols.makeChild(canonicalize, intern)); - } - - /* - /********************************************* - /* Internal methods, parsing - /********************************************* - */ - - /** - * @return True if a BOM was succesfully found, and encoding - * thereby recognized. - */ - private boolean handleBOM(int quad) - throws IOException - { - /* Handling of (usually) optional BOM (required for - * multi-byte formats); first 32-bit charsets: - */ - switch (quad) { - case 0x0000FEFF: - _bigEndian = true; - _inputPtr += 4; - _bytesPerChar = 4; - return true; - case 0xFFFE0000: // UCS-4, LE? - _inputPtr += 4; - _bytesPerChar = 4; - _bigEndian = false; - return true; - case 0x0000FFFE: // UCS-4, in-order... - reportWeirdUCS4("2143"); // throws exception - case 0xFEFF0000: // UCS-4, in-order... - reportWeirdUCS4("3412"); // throws exception - } - // Ok, if not, how about 16-bit encoding BOMs? - int msw = quad >>> 16; - if (msw == 0xFEFF) { // UTF-16, BE - _inputPtr += 2; - _bytesPerChar = 2; - _bigEndian = true; - return true; - } - if (msw == 0xFFFE) { // UTF-16, LE - _inputPtr += 2; - _bytesPerChar = 2; - _bigEndian = false; - return true; - } - // And if not, then UTF-8 BOM? - if ((quad >>> 8) == 0xEFBBBF) { // UTF-8 - _inputPtr += 3; - _bytesPerChar = 1; - _bigEndian = true; // doesn't really matter - return true; - } - return false; - } - - private boolean checkUTF32(int quad) - throws IOException - { - /* Handling of (usually) optional BOM (required for - * multi-byte formats); first 32-bit charsets: - */ - if ((quad >> 8) == 0) { // 0x000000?? -> UTF32-BE - _bigEndian = true; - } else if ((quad & 0x00FFFFFF) == 0) { // 0x??000000 -> UTF32-LE - _bigEndian = false; - } else if ((quad & ~0x00FF0000) == 0) { // 0x00??0000 -> UTF32-in-order - reportWeirdUCS4("3412"); - } else if ((quad & ~0x0000FF00) == 0) { // 0x0000??00 -> UTF32-in-order - reportWeirdUCS4("2143"); - } else { - // Can not be valid UTF-32 encoded JSON... - return false; - } - // Not BOM (just regular content), nothing to skip past: - //_inputPtr += 4; - _bytesPerChar = 4; - return true; - } - - private boolean checkUTF16(int i16) - { - if ((i16 & 0xFF00) == 0) { // UTF-16BE - _bigEndian = true; - } else if ((i16 & 0x00FF) == 0) { // UTF-16LE - _bigEndian = false; - } else { // nope, not UTF-16 - return false; - } - // Not BOM (just regular content), nothing to skip past: - //_inputPtr += 2; - _bytesPerChar = 2; - return true; - } - - /* - /********************************************* - /* Internal methods, problem reporting - /********************************************* - */ - - private void reportWeirdUCS4(String type) - throws IOException - { - throw new CharConversionException("Unsupported UCS-4 endianness ("+type+") detected"); - } - - /* - /********************************************* - /* Internal methods, raw input access - /********************************************* - */ - - protected boolean ensureLoaded(int minimum) - throws IOException - { - /* Let's assume here buffer has enough room -- this will always - * be true for the limited used this method gets - */ - int gotten = (_inputEnd - _inputPtr); - while (gotten < minimum) { - int count; - - if (_in == null) { // block source - count = -1; - } else { - count = _in.read(_inputBuffer, _inputEnd, _inputBuffer.length - _inputEnd); - } - if (count < 1) { - return false; - } - _inputEnd += count; - gotten += count; - } - return true; - } -} - diff --git a/src/org/codehaus/jackson/impl/DefaultPrettyPrinter.java b/src/org/codehaus/jackson/impl/DefaultPrettyPrinter.java deleted file mode 100644 index 2424c34499..0000000000 --- a/src/org/codehaus/jackson/impl/DefaultPrettyPrinter.java +++ /dev/null @@ -1,264 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; -import java.util.Arrays; - -import org.codehaus.jackson.*; - -/** - * Default {@link PrettyPrinter} implementation that uses 2-space - * indentation with platform-default linefeeds. - * Usually this class is not instantiated directly, but instead - * method {@link JsonGenerator#useDefaultPrettyPrinter} is - * used, which will use an instance of this class for operation. - */ -public class DefaultPrettyPrinter - implements PrettyPrinter -{ - // // // Config, indentation - - /** - * By default, let's use only spaces to separate array values. - */ - protected Indenter _arrayIndenter = new FixedSpaceIndenter(); - - /** - * By default, let's use linefeed-adding indenter for separate - * object entries. We'll further configure indenter to use - * system-specific linefeeds, and 2 spaces per level (as opposed to, - * say, single tabs) - */ - protected Indenter _objectIndenter = new Lf2SpacesIndenter(); - - // // // Config, other white space configuration - - /** - * By default we will add spaces around colons used to - * separate object fields and values. - * If disabled, will not use spaces around colon. - */ - protected boolean _spacesInObjectEntries = true; - - // // // State: - - /** - * Number of open levels of nesting. Used to determine amount of - * indentation to use. - */ - protected int _nesting = 0; - - /* - //////////////////////////////////////////////////////////// - // Life-cycle (construct, configure) - //////////////////////////////////////////////////////////// - */ - - public DefaultPrettyPrinter() { } - - public void indentArraysWith(Indenter i) - { - _arrayIndenter = (i == null) ? new NopIndenter() : i; - } - - public void indentObjectsWith(Indenter i) - { - _objectIndenter = (i == null) ? new NopIndenter() : i; - } - - public void spacesInObjectEntries(boolean b) { _spacesInObjectEntries = b; } - /* - //////////////////////////////////////////////////////////// - // PrettyPrinter impl - //////////////////////////////////////////////////////////// - */ - - public void writeRootValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException - { - jg.writeRaw(' '); - } - - public void writeStartObject(JsonGenerator jg) - throws IOException, JsonGenerationException - { - jg.writeRaw('{'); - if (!_objectIndenter.isInline()) { - ++_nesting; - } - } - - public void beforeObjectEntries(JsonGenerator jg) - throws IOException, JsonGenerationException - { - _objectIndenter.writeIndentation(jg, _nesting); - } - - /** - * Method called after an object field has been output, but - * before the value is output. - *

- * Default handling (without pretty-printing) will output a single - * colon to separate the two. Pretty-printer is - * to output a colon as well, but can surround that with other - * (white-space) decoration. - */ - public void writeObjectFieldValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException - { - if (_spacesInObjectEntries) { - jg.writeRaw(" : "); - } else { - jg.writeRaw(':'); - } - } - - /** - * Method called after an object entry (field:value) has been completely - * output, and before another value is to be output. - *

- * Default handling (without pretty-printing) will output a single - * comma to separate the two. Pretty-printer is - * to output a comma as well, but can surround that with other - * (white-space) decoration. - */ - public void writeObjectEntrySeparator(JsonGenerator jg) - throws IOException, JsonGenerationException - { - jg.writeRaw(','); - _objectIndenter.writeIndentation(jg, _nesting); - } - - public void writeEndObject(JsonGenerator jg, int nrOfEntries) - throws IOException, JsonGenerationException - { - if (!_objectIndenter.isInline()) { - --_nesting; - } - if (nrOfEntries > 0) { - _objectIndenter.writeIndentation(jg, _nesting); - } else { - jg.writeRaw(' '); - } - jg.writeRaw('}'); - } - - public void writeStartArray(JsonGenerator jg) - throws IOException, JsonGenerationException - { - if (!_arrayIndenter.isInline()) { - ++_nesting; - } - jg.writeRaw('['); - } - - public void beforeArrayValues(JsonGenerator jg) - throws IOException, JsonGenerationException - { - _arrayIndenter.writeIndentation(jg, _nesting); - } - - /** - * Method called after an array value has been completely - * output, and before another value is to be output. - *

- * Default handling (without pretty-printing) will output a single - * comma to separate the two. Pretty-printer is - * to output a comma as well, but can surround that with other - * (white-space) decoration. - */ - public void writeArrayValueSeparator(JsonGenerator jg) - throws IOException, JsonGenerationException - { - jg.writeRaw(','); - _arrayIndenter.writeIndentation(jg, _nesting); - } - - public void writeEndArray(JsonGenerator jg, int nrOfValues) - throws IOException, JsonGenerationException - { - if (!_arrayIndenter.isInline()) { - --_nesting; - } - if (nrOfValues > 0) { - _arrayIndenter.writeIndentation(jg, _nesting); - } else { - jg.writeRaw(' '); - } - jg.writeRaw(']'); - } - - /* - //////////////////////////////////////////////////////////// - // Helper classes - //////////////////////////////////////////////////////////// - */ - - /** - * Dummy implementation that adds no indentation whatsoever - */ - public static class NopIndenter - implements Indenter - { - public NopIndenter() { } - public void writeIndentation(JsonGenerator jg, int level) { } - public boolean isInline() { return true; } - } - - /** - * This is a very simple indenter that only every adds a - * single space for indentation. It is used as the default - * indenter for array values. - */ - public static class FixedSpaceIndenter - implements Indenter - { - public FixedSpaceIndenter() { } - - public void writeIndentation(JsonGenerator jg, int level) - throws IOException, JsonGenerationException - { - jg.writeRaw(' '); - } - - public boolean isInline() { return true; } - } - - /** - * Default linefeed-based indenter uses system-specific linefeeds and - * 2 spaces for indentation per level. - */ - public static class Lf2SpacesIndenter - implements Indenter - { - final static String SYSTEM_LINE_SEPARATOR; - static { - String lf = null; - try { - lf = System.getProperty("line.separator"); - } catch (Throwable t) { } // access exception? - SYSTEM_LINE_SEPARATOR = (lf == null) ? "\n" : lf; - } - - final static int SPACE_COUNT = 64; - final static char[] SPACES = new char[SPACE_COUNT]; - static { - Arrays.fill(SPACES, ' '); - } - - public Lf2SpacesIndenter() { } - - public boolean isInline() { return false; } - - public void writeIndentation(JsonGenerator jg, int level) - throws IOException, JsonGenerationException - { - jg.writeRaw(SYSTEM_LINE_SEPARATOR); - level += level; // 2 spaces per level - while (level > SPACE_COUNT) { // should never happen but... - jg.writeRaw(SPACES, 0, SPACE_COUNT); - level -= SPACES.length; - } - jg.writeRaw(SPACES, 0, level); - } - } -} diff --git a/src/org/codehaus/jackson/impl/Indenter.java b/src/org/codehaus/jackson/impl/Indenter.java deleted file mode 100644 index 6249f55efa..0000000000 --- a/src/org/codehaus/jackson/impl/Indenter.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.IOException; - -import org.codehaus.jackson.*; - -/** - * Interface that defines objects that can produce indentation used - * to separate object entries and array values. Indentation in this - * context just means insertion of white space, independent of whether - * linefeeds are output. - */ -public interface Indenter -{ - public void writeIndentation(JsonGenerator jg, int level) - throws IOException, JsonGenerationException; - - /** - * @return True if indenter is considered inline (does not add linefeeds), - * false otherwise - */ - public boolean isInline(); -} diff --git a/src/org/codehaus/jackson/impl/JsonGeneratorBase.java b/src/org/codehaus/jackson/impl/JsonGeneratorBase.java deleted file mode 100644 index cf459c7f84..0000000000 --- a/src/org/codehaus/jackson/impl/JsonGeneratorBase.java +++ /dev/null @@ -1,508 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import org.codehaus.jackson.*; - -/** - * This base class implements part of API that a JSON generator exposes - * to applications, adds shared internal methods that sub-classes - * can use and adds some abstract methods sub-classes must implement. - */ -public abstract class JsonGeneratorBase - extends JsonGenerator -{ - /* - //////////////////////////////////////////////////// - // Configuration - //////////////////////////////////////////////////// - */ - - protected ObjectCodec _objectCodec; - - /** - * Bit flag composed of bits that indicate which - * {@link org.codehaus.jackson.JsonGenerator.Feature}s - * are enabled. - */ - protected int _features; - - /** - * Flag set to indicate that implicit conversion from number - * to JSON String is needed (as per - * {@link org.codehaus.jackson.JsonGenerator.Feature#WRITE_NUMBERS_AS_STRINGS}). - */ - protected boolean _cfgNumbersAsStrings; - - /* - //////////////////////////////////////////////////// - // State - //////////////////////////////////////////////////// - */ - - /** - * Object that keeps track of the current contextual state - * of the generator. - */ - protected JsonWriteContext _writeContext; - - /** - * Flag that indicates whether generator is closed or not. Gets - * set when it is closed by an explicit call - * ({@link #close}). - */ - protected boolean _closed; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - protected JsonGeneratorBase(int features, ObjectCodec codec) - { - super(); - _features = features; - _writeContext = JsonWriteContext.createRootContext(); - _objectCodec = codec; - _cfgNumbersAsStrings = isEnabled(Feature.WRITE_NUMBERS_AS_STRINGS); - } - - /* - //////////////////////////////////////////////////// - // Configuration - //////////////////////////////////////////////////// - */ - - @Override - public JsonGenerator enable(Feature f) { - _features |= f.getMask(); - if (f == Feature.WRITE_NUMBERS_AS_STRINGS) { - _cfgNumbersAsStrings = true; - } - return this; - } - - @Override - public JsonGenerator disable(Feature f) { - _features &= ~f.getMask(); - if (f == Feature.WRITE_NUMBERS_AS_STRINGS) { - _cfgNumbersAsStrings = false; - } - return this; - } - - //public JsonGenerator configure(Feature f, boolean state) { } - - @Override - public final boolean isEnabled(Feature f) { - return (_features & f.getMask()) != 0; - } - - public final JsonGenerator useDefaultPrettyPrinter() - { - return setPrettyPrinter(new DefaultPrettyPrinter()); - } - - public final JsonGenerator setCodec(ObjectCodec oc) { - _objectCodec = oc; - return this; - } - - public final ObjectCodec getCodec() { return _objectCodec; } - - /* - //////////////////////////////////////////////////// - // Public API, accessors - //////////////////////////////////////////////////// - */ - - /** - * Note: co-variant return type. - */ - public final JsonWriteContext getOutputContext() { return _writeContext; } - - /* - //////////////////////////////////////////////////// - // Public API, write methods, structural - //////////////////////////////////////////////////// - */ - - public final void writeStartArray() - throws IOException, JsonGenerationException - { - // Array is a value, need to verify it's allowed - _verifyValueWrite("start an array"); - _writeContext = _writeContext.createChildArrayContext(); - if (_cfgPrettyPrinter != null) { - _cfgPrettyPrinter.writeStartArray(this); - } else { - _writeStartArray(); - } - } - - protected abstract void _writeStartArray() - throws IOException, JsonGenerationException; - - public final void writeEndArray() - throws IOException, JsonGenerationException - { - if (!_writeContext.inArray()) { - _reportError("Current context not an ARRAY but "+_writeContext.getTypeDesc()); - } - if (_cfgPrettyPrinter != null) { - _cfgPrettyPrinter.writeEndArray(this, _writeContext.getEntryCount()); - } else { - _writeEndArray(); - } - _writeContext = _writeContext.getParent(); - } - - protected abstract void _writeEndArray() - throws IOException, JsonGenerationException; - - public final void writeStartObject() - throws IOException, JsonGenerationException - { - _verifyValueWrite("start an object"); - _writeContext = _writeContext.createChildObjectContext(); - if (_cfgPrettyPrinter != null) { - _cfgPrettyPrinter.writeStartObject(this); - } else { - _writeStartObject(); - } - } - - protected abstract void _writeStartObject() - throws IOException, JsonGenerationException; - - public final void writeEndObject() - throws IOException, JsonGenerationException - { - if (!_writeContext.inObject()) { - _reportError("Current context not an object but "+_writeContext.getTypeDesc()); - } - _writeContext = _writeContext.getParent(); - if (_cfgPrettyPrinter != null) { - _cfgPrettyPrinter.writeEndObject(this, _writeContext.getEntryCount()); - } else { - _writeEndObject(); - } - } - - protected abstract void _writeEndObject() - throws IOException, JsonGenerationException; - - public final void writeFieldName(String name) - throws IOException, JsonGenerationException - { - // Object is a value, need to verify it's allowed - int status = _writeContext.writeFieldName(name); - if (status == JsonWriteContext.STATUS_EXPECT_VALUE) { - _reportError("Can not write a field name, expecting a value"); - } - _writeFieldName(name, (status == JsonWriteContext.STATUS_OK_AFTER_COMMA)); - } - - protected abstract void _writeFieldName(String name, boolean commaBefore) - throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API, write methods, textual - //////////////////////////////////////////////////// - */ - - //public abstract void writeString(String text) throws IOException, JsonGenerationException; - - //public abstract void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException; - - //public abstract void writeRaw(String text) throws IOException, JsonGenerationException; - - //public abstract void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException; - - //public abstract void writeBinary(byte[] data, int offset, int len, boolean includeLFs) throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API, write methods, primitive - //////////////////////////////////////////////////// - */ - - public abstract void writeNumber(int i) - throws IOException, JsonGenerationException; - - public abstract void writeNumber(long l) - throws IOException, JsonGenerationException; - - public abstract void writeNumber(double d) - throws IOException, JsonGenerationException; - - public abstract void writeNumber(float f) - throws IOException, JsonGenerationException; - - public abstract void writeNumber(BigDecimal dec) - throws IOException, JsonGenerationException; - - public abstract void writeBoolean(boolean state) - throws IOException, JsonGenerationException; - - public abstract void writeNull() - throws IOException, JsonGenerationException; - - /* - //////////////////////////////////////////////////// - // Public API, write methods, POJOs, trees - //////////////////////////////////////////////////// - */ - - public void writeObject(Object value) - throws IOException, JsonProcessingException - { - if (value == null) { - // important: call method that does check value write: - writeNull(); - } else { - /* 02-Mar-2009, tatu: we are NOT to call _verifyValueWrite here, - * because that will be done when codec actually serializes - * contained POJO. If we did call it it would advance state - * causing exception later on - */ - if (_objectCodec != null) { - _objectCodec.writeValue(this, value); - return; - } - _writeSimpleObject(value); - } - } - - public void writeTree(JsonNode rootNode) - throws IOException, JsonProcessingException - { - // As with 'writeObject()', we are not check if write would work - if (rootNode == null) { - writeNull(); - } else { - if (_objectCodec == null) { - throw new IllegalStateException("No ObjectCodec defined for the generator, can not serialize JsonNode-based trees"); - } - _objectCodec.writeTree(this, rootNode); - } - } - - /* - //////////////////////////////////////////////////// - // Public API, low-level output handling - //////////////////////////////////////////////////// - */ - - public abstract void flush() throws IOException; - - public void close() throws IOException - { - _closed = true; - } - - public boolean isClosed() { return _closed; } - - /* - //////////////////////////////////////////////////// - // Public API, copy-through methods - //////////////////////////////////////////////////// - */ - - public final void copyCurrentEvent(JsonParser jp) - throws IOException, JsonProcessingException - { - switch(jp.getCurrentToken()) { - case START_OBJECT: - writeStartObject(); - break; - case END_OBJECT: - writeEndObject(); - break; - case START_ARRAY: - writeStartArray(); - break; - case END_ARRAY: - writeEndArray(); - break; - case FIELD_NAME: - writeFieldName(jp.getCurrentName()); - break; - case VALUE_STRING: - writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength()); - break; - case VALUE_NUMBER_INT: - switch (jp.getNumberType()) { - case INT: - writeNumber(jp.getIntValue()); - break; - case BIG_INTEGER: - writeNumber(jp.getBigIntegerValue()); - break; - default: - writeNumber(jp.getLongValue()); - } - break; - case VALUE_NUMBER_FLOAT: - switch (jp.getNumberType()) { - case BIG_DECIMAL: - writeNumber(jp.getDecimalValue()); - break; - case FLOAT: - writeNumber(jp.getFloatValue()); - break; - default: - writeNumber(jp.getDoubleValue()); - } - break; - case VALUE_TRUE: - writeBoolean(true); - break; - case VALUE_FALSE: - writeBoolean(false); - break; - case VALUE_NULL: - writeNull(); - break; - case VALUE_EMBEDDED_OBJECT: - writeObject(jp.getEmbeddedObject()); - break; - default: - _cantHappen(); - } - } - - public final void copyCurrentStructure(JsonParser jp) - throws IOException, JsonProcessingException - { - JsonToken t = jp.getCurrentToken(); - - // Let's handle field-name separately first - if (t == JsonToken.FIELD_NAME) { - writeFieldName(jp.getCurrentName()); - t = jp.nextToken(); - // fall-through to copy the associated value - } - - switch (t) { - case START_ARRAY: - writeStartArray(); - while (jp.nextToken() != JsonToken.END_ARRAY) { - copyCurrentStructure(jp); - } - writeEndArray(); - break; - case START_OBJECT: - writeStartObject(); - while (jp.nextToken() != JsonToken.END_OBJECT) { - copyCurrentStructure(jp); - } - writeEndObject(); - break; - default: // others are simple: - copyCurrentEvent(jp); - } - } - - /* - //////////////////////////////////////////////////// - // Package methods for this, sub-classes - //////////////////////////////////////////////////// - */ - - protected abstract void _releaseBuffers(); - - protected abstract void _verifyValueWrite(String typeMsg) - throws IOException, JsonGenerationException; - - protected void _reportError(String msg) - throws JsonGenerationException - { - throw new JsonGenerationException(msg); - } - - protected void _cantHappen() - { - throw new RuntimeException("Internal error: should never end up through this code path"); - } - - /** - * Helper method to try to call appropriate write method for given untyped Object.At this point, no structural - * conversions should be done, only simple basic types are to be coerced as necessary. - * - * @param value Non-null value to write - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - protected void _writeSimpleObject(Object value) - throws IOException, JsonGenerationException - { - /* 31-Dec-2009, tatu: Actually, we could just handle some basic - * types even without codec. This can improve interoperability, - * and specifically help with TokenBuffer. - */ - if (value == null) { - writeNull(); - return; - } - if (value instanceof String) { - writeString((String) value); - return; - } - if (value instanceof Number) { - Number n = (Number) value; - if (n instanceof Integer) { - writeNumber(n.intValue()); - return; - } else if (n instanceof Long) { - writeNumber(n.longValue()); - return; - } else if (n instanceof Double) { - writeNumber(n.doubleValue()); - return; - } else if (n instanceof Float) { - writeNumber(n.floatValue()); - return; - } else if (n instanceof Short) { - writeNumber(n.shortValue()); - return; - } else if (n instanceof Byte) { - writeNumber(n.byteValue()); - return; - } else if (n instanceof BigInteger) { - writeNumber((BigInteger) n); - return; - } else if (n instanceof BigDecimal) { - writeNumber((BigDecimal) n); - return; - - // then Atomic types - - } else if (n instanceof AtomicInteger) { - writeNumber(((AtomicInteger) n).get()); - return; - } else if (n instanceof AtomicLong) { - writeNumber(((AtomicLong) n).get()); - return; - } - } else if (value instanceof byte[]) { - writeBinary((byte[]) value); - return; - } else if (value instanceof Boolean) { - writeBoolean(((Boolean) value).booleanValue()); - return; - } else if (value instanceof AtomicBoolean) { - writeBoolean(((AtomicBoolean) value).get()); - return; - } - throw new IllegalStateException("No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed " - +value.getClass().getName()+")"); - } -} diff --git a/src/org/codehaus/jackson/impl/JsonNumericParserBase.java b/src/org/codehaus/jackson/impl/JsonNumericParserBase.java deleted file mode 100644 index 67a2caeb45..0000000000 --- a/src/org/codehaus/jackson/impl/JsonNumericParserBase.java +++ /dev/null @@ -1,590 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.math.BigDecimal; -import java.math.BigInteger; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.io.NumberInput; - -/** - * Another intermediate base class used by all Jackson {@link JsonParser} - * implementations. Contains shared functionality for dealing with - * number parsing aspects, independent of input source decoding. - * - * @author Tatu Saloranta - */ -public abstract class JsonNumericParserBase - extends JsonParserBase -{ - /* Additionally we need to be able to distinguish between - * various numeric representations, since we try to use - * the fastest one that works for given textual representation. - */ - - final protected static int NR_UNKNOWN = 0; - - // First, integer types - - final protected static int NR_INT = 0x0001; - final protected static int NR_LONG = 0x0002; - final protected static int NR_BIGINT = 0x0004; - - // And then floating point types - - final protected static int NR_DOUBLE = 0x008; - final protected static int NR_BIGDECIMAL = 0x0010; - - // Also, we need some numeric constants - - final static BigDecimal BD_MIN_LONG = new BigDecimal(Long.MIN_VALUE); - final static BigDecimal BD_MAX_LONG = new BigDecimal(Long.MAX_VALUE); - - final static BigDecimal BD_MIN_INT = new BigDecimal(Long.MIN_VALUE); - final static BigDecimal BD_MAX_INT = new BigDecimal(Long.MAX_VALUE); - - final static long MIN_INT_L = (long) Integer.MIN_VALUE; - final static long MAX_INT_L = (long) Integer.MAX_VALUE; - - // These are not very accurate, but have to do... (for bounds checks) - - final static double MIN_LONG_D = (double) Long.MIN_VALUE; - final static double MAX_LONG_D = (double) Long.MAX_VALUE; - - final static double MIN_INT_D = (double) Integer.MIN_VALUE; - final static double MAX_INT_D = (double) Integer.MAX_VALUE; - - - // Digits, numeric - final protected static int INT_0 = '0'; - final protected static int INT_1 = '1'; - final protected static int INT_2 = '2'; - final protected static int INT_3 = '3'; - final protected static int INT_4 = '4'; - final protected static int INT_5 = '5'; - final protected static int INT_6 = '6'; - final protected static int INT_7 = '7'; - final protected static int INT_8 = '8'; - final protected static int INT_9 = '9'; - - final protected static int INT_MINUS = '-'; - final protected static int INT_PLUS = '+'; - final protected static int INT_DECIMAL_POINT = '.'; - - final protected static int INT_e = 'e'; - final protected static int INT_E = 'E'; - - final protected static char CHAR_NULL = '\0'; - - /* - //////////////////////////////////////////////////// - // Numeric value holders: multiple fields used for - // for efficiency - //////////////////////////////////////////////////// - */ - - /** - * Bitfield that indicates which numeric representations - * have been calculated for the current type - */ - protected int _numTypesValid = NR_UNKNOWN; - - // First primitives - - protected int _numberInt; - - protected long _numberLong; - - protected double _numberDouble; - - // And then object types - - protected BigInteger _numberBigInt; - - protected BigDecimal _numberBigDecimal; - - // And then other information about value itself - - /** - * Flag that indicates whether numeric value has a negative - * value. That is, whether its textual representation starts - * with minus character. - */ - protected boolean _numberNegative; - - /** - * Length of integer part of the number, in characters - */ - protected int mIntLength; - - /** - * Length of the fractional part (not including decimal - * point or exponent), in characters. - * Not used for pure integer values. - */ - protected int mFractLength; - - /** - * Length of the exponent part of the number, if any, not - * including 'e' marker or sign, just digits. - * Not used for pure integer values. - */ - protected int mExpLength; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - protected JsonNumericParserBase(IOContext ctxt, int features) - { - super(ctxt, features); - } - - protected final JsonToken reset(boolean negative, int intLen, int fractLen, int expLen) - { - _numberNegative = negative; - mIntLength = intLen; - mFractLength = fractLen; - mExpLength = expLen; - _numTypesValid = NR_UNKNOWN; // to force parsing - if (fractLen < 1 && expLen < 1) { // integer - return JsonToken.VALUE_NUMBER_INT; - } - // Nope, floating point - return JsonToken.VALUE_NUMBER_FLOAT; - } - - /* - //////////////////////////////////////////////////// - // Additional methods for sub-classes to implement - //////////////////////////////////////////////////// - */ - - protected abstract JsonToken parseNumberText(int ch) - throws IOException, JsonParseException; - - /* - //////////////////////////////////////////////////// - // Numeric accessors of public API - //////////////////////////////////////////////////// - */ - - public Number getNumberValue() - throws IOException, JsonParseException - { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_UNKNOWN); // will also check event type - } - // Separate types for int types - if (_currToken == JsonToken.VALUE_NUMBER_INT) { - if ((_numTypesValid & NR_INT) != 0) { - return Integer.valueOf(_numberInt); - } - if ((_numTypesValid & NR_LONG) != 0) { - return Long.valueOf(_numberLong); - } - if ((_numTypesValid & NR_BIGINT) != 0) { - return _numberBigInt; - } - // Shouldn't get this far but if we do - return _numberBigDecimal; - } - - /* And then floating point types. But here optimal type - * needs to be big decimal, to avoid losing any data? - */ - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return _numberBigDecimal; - } - if ((_numTypesValid & NR_DOUBLE) == 0) { // sanity check - _throwInternal(); - } - return Double.valueOf(_numberDouble); - } - - public NumberType getNumberType() - throws IOException, JsonParseException - { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_UNKNOWN); // will also check event type - } - if (_currToken == JsonToken.VALUE_NUMBER_INT) { - if ((_numTypesValid & NR_INT) != 0) { - return NumberType.INT; - } - if ((_numTypesValid & NR_LONG) != 0) { - return NumberType.LONG; - } - return NumberType.BIG_INTEGER; - } - - /* And then floating point types. Here optimal type - * needs to be big decimal, to avoid losing any data? - * However... using BD is slow, so let's allow returning - * double as type if no explicit call has been made to access - * data as BD? - */ - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - return NumberType.BIG_DECIMAL; - } - return NumberType.DOUBLE; - } - - public int getIntValue() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_INT) == 0) { - if (_numTypesValid == NR_UNKNOWN) { // not parsed at all - parseNumericValue(NR_INT); // will also check event type - } - if ((_numTypesValid & NR_INT) == 0) { // wasn't an int natively? - convertNumberToInt(); // let's make it so, if possible - } - } - return _numberInt; - } - - public long getLongValue() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_LONG) == 0) { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_LONG); - } - if ((_numTypesValid & NR_LONG) == 0) { - convertNumberToLong(); - } - } - return _numberLong; - } - - public BigInteger getBigIntegerValue() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_BIGINT) == 0) { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_BIGINT); - } - if ((_numTypesValid & NR_BIGINT) == 0) { - convertNumberToBigInteger(); - } - } - return _numberBigInt; - } - - public float getFloatValue() - throws IOException, JsonParseException - { - double value = getDoubleValue(); - /* 22-Jan-2009, tatu: Bounds/range checks would be tricky - * here, so let's not bother even trying... - */ - /* - if (value < -Float.MAX_VALUE || value > MAX_FLOAT_D) { - _reportError("Numeric value ("+getText()+") out of range of Java float"); - } - */ - return (float) value; - } - - public double getDoubleValue() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_DOUBLE) == 0) { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_DOUBLE); - } - if ((_numTypesValid & NR_DOUBLE) == 0) { - convertNumberToDouble(); - } - } - return _numberDouble; - } - - public BigDecimal getDecimalValue() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_BIGDECIMAL) == 0) { - if (_numTypesValid == NR_UNKNOWN) { - parseNumericValue(NR_BIGDECIMAL); - } - if ((_numTypesValid & NR_BIGDECIMAL) == 0) { - convertNumberToBigDecimal(); - } - } - return _numberBigDecimal; - } - - - /* - //////////////////////////////////////////////////// - // Conversion from textual to numeric representation - //////////////////////////////////////////////////// - */ - - /** - * Method that will parse actual numeric value out of a syntactically valid number value.Type it will parse into - * depends on whether it is a floating point number, as well as its magnitude: smallest legal type (of ones - * available) is used for efficiency. - * - * @param expType Numeric type that we will immediately need, if any; mostly necessary to optimize handling of - * floating point numbers - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected final void parseNumericValue(int expType) - throws JsonParseException - { - // First things first: must be a numeric event - if (_currToken == null || !_currToken.isNumeric()) { - _reportError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); - } - try { - // Int or float? - if (_currToken == JsonToken.VALUE_NUMBER_INT) { - char[] buf = _textBuffer.getTextBuffer(); - int offset = _textBuffer.getTextOffset(); - int len = mIntLength; - if (_numberNegative) { - ++offset; - } - if (len <= 9) { // definitely fits in int - int i = NumberInput.parseInt(buf, offset, len); - _numberInt = _numberNegative ? -i : i; - _numTypesValid = NR_INT; - return; - } - if (len <= 18) { // definitely fits AND is easy to parse using 2 int parse calls - long l = NumberInput.parseLong(buf, offset, len); - if (_numberNegative) { - l = -l; - } - // [JACKSON-230] Could still fit in int, need to check - if (len == 10) { - if (_numberNegative) { - if (l >= MIN_INT_L) { - _numberInt = (int) l; - _numTypesValid = NR_INT; - return; - } - } else { - if (l <= MAX_INT_L) { - _numberInt = (int) l; - _numTypesValid = NR_INT; - return; - } - } - } - _numberLong = l; - _numTypesValid = NR_LONG; - return; - } - String numStr = _textBuffer.contentsAsString(); - // [JACKSON-230] Some long cases still... - if (NumberInput.inLongRange(buf, offset, len, _numberNegative)) { - // Probably faster to construct a String, call parse, than to use BigInteger - _numberLong = Long.parseLong(numStr); - _numTypesValid = NR_LONG; - return; - } - // nope, need the heavy guns... (rare case) - _numberBigInt = new BigInteger(numStr); - _numTypesValid = NR_BIGINT; - return; - } - - /* Nope: floating point. Here we need to be careful to get - * optimal parsing strategy: choice is between accurate but - * slow (BigDecimal) and lossy but fast (Double). For now - * let's only use BD when explicitly requested -- it can - * still be constructed correctly at any point since we do - * retain textual representation - */ - if (expType == NR_BIGDECIMAL) { - _numberBigDecimal = _textBuffer.contentsAsDecimal(); - _numTypesValid = NR_BIGDECIMAL; - } else { - // Otherwise double has to do - _numberDouble = _textBuffer.contentsAsDouble(); - _numTypesValid = NR_DOUBLE; - } - } catch (NumberFormatException nex) { - // Can this ever occur? Due to overflow, maybe? - _wrapError("Malformed numeric value '"+_textBuffer.contentsAsString()+"'", nex); - } - } - - /* - //////////////////////////////////////////////////// - // Conversions - //////////////////////////////////////////////////// - */ - - protected void convertNumberToInt() - throws IOException, JsonParseException - { - // First, converting from long ought to be easy - if ((_numTypesValid & NR_LONG) != 0) { - // Let's verify it's lossless conversion by simple roundtrip - int result = (int) _numberLong; - if (((long) result) != _numberLong) { - _reportError("Numeric value ("+getText()+") out of range of int"); - } - _numberInt = result; - } else if ((_numTypesValid & NR_BIGINT) != 0) { - // !!! Should check for range... - _numberInt = _numberBigInt.intValue(); - } else if ((_numTypesValid & NR_DOUBLE) != 0) { - // Need to check boundaries - if (_numberDouble < MIN_INT_D || _numberDouble > MAX_INT_D) { - reportOverflowInt(); - } - _numberInt = (int) _numberDouble; - } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - if (BD_MIN_INT.compareTo(_numberBigDecimal) > 0 - || BD_MAX_INT.compareTo(_numberBigDecimal) < 0) { - reportOverflowInt(); - } - _numberInt = _numberBigDecimal.intValue(); - } else { - _throwInternal(); // should never get here - } - - _numTypesValid |= NR_INT; - } - - protected void convertNumberToLong() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_INT) != 0) { - _numberLong = (long) _numberInt; - } else if ((_numTypesValid & NR_BIGINT) != 0) { - // !!! Should check for range... - _numberLong = _numberBigInt.longValue(); - } else if ((_numTypesValid & NR_DOUBLE) != 0) { - // Need to check boundaries - if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) { - reportOverflowLong(); - } - _numberLong = (long) _numberDouble; - } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - if (BD_MIN_LONG.compareTo(_numberBigDecimal) > 0 - || BD_MAX_LONG.compareTo(_numberBigDecimal) < 0) { - reportOverflowLong(); - } - _numberLong = _numberBigDecimal.longValue(); - } else { - _throwInternal(); // should never get here - } - - _numTypesValid |= NR_LONG; - } - - protected void convertNumberToBigInteger() - throws IOException, JsonParseException - { - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - // here it'll just get truncated, no exceptions thrown - _numberBigInt = _numberBigDecimal.toBigInteger(); - } else if ((_numTypesValid & NR_LONG) != 0) { - _numberBigInt = BigInteger.valueOf(_numberLong); - } else if ((_numTypesValid & NR_INT) != 0) { - _numberBigInt = BigInteger.valueOf(_numberInt); - } else if ((_numTypesValid & NR_DOUBLE) != 0) { - _numberBigInt = BigDecimal.valueOf(_numberDouble).toBigInteger(); - } else { - _throwInternal(); // should never get here - } - _numTypesValid |= NR_BIGINT; - } - - protected void convertNumberToDouble() - throws IOException, JsonParseException - { - /* 05-Aug-2008, tatus: Important note: this MUST start with - * more accurate representations, since we don't know which - * value is the original one (others get generated when - * requested) - */ - - if ((_numTypesValid & NR_BIGDECIMAL) != 0) { - _numberDouble = _numberBigDecimal.doubleValue(); - } else if ((_numTypesValid & NR_BIGINT) != 0) { - _numberDouble = _numberBigInt.doubleValue(); - } else if ((_numTypesValid & NR_LONG) != 0) { - _numberDouble = (double) _numberLong; - } else if ((_numTypesValid & NR_INT) != 0) { - _numberDouble = (double) _numberInt; - } else { - _throwInternal(); // should never get here - } - - _numTypesValid |= NR_DOUBLE; - } - - protected void convertNumberToBigDecimal() - throws IOException, JsonParseException - { - /* 05-Aug-2008, tatus: Important note: this MUST start with - * more accurate representations, since we don't know which - * value is the original one (others get generated when - * requested) - */ - - if ((_numTypesValid & NR_DOUBLE) != 0) { - /* Let's actually parse from String representation, - * to avoid rounding errors that non-decimal floating operations - * would incur - */ - _numberBigDecimal = new BigDecimal(getText()); - } else if ((_numTypesValid & NR_BIGINT) != 0) { - _numberBigDecimal = new BigDecimal(_numberBigInt); - } else if ((_numTypesValid & NR_LONG) != 0) { - _numberBigDecimal = BigDecimal.valueOf(_numberLong); - } else if ((_numTypesValid & NR_INT) != 0) { - _numberBigDecimal = BigDecimal.valueOf((long) _numberInt); - } else { - _throwInternal(); // should never get here - } - _numTypesValid |= NR_BIGDECIMAL; - } - - /* - //////////////////////////////////////////////////// - // Exception reporting - //////////////////////////////////////////////////// - */ - - protected void reportUnexpectedNumberChar(int ch, String comment) - throws JsonParseException - { - String msg = "Unexpected character ("+_getCharDesc(ch)+") in numeric value"; - if (comment != null) { - msg += ": "+comment; - } - _reportError(msg); - } - - protected void reportInvalidNumber(String msg) - throws JsonParseException - { - _reportError("Invalid numeric value: "+msg); - } - - - protected void reportOverflowInt() - throws IOException, JsonParseException - { - _reportError("Numeric value ("+getText()+") out of range of int ("+Integer.MIN_VALUE+" - "+Integer.MAX_VALUE+")"); - } - - protected void reportOverflowLong() - throws IOException, JsonParseException - { - _reportError("Numeric value ("+getText()+") out of range of long ("+Long.MIN_VALUE+" - "+Long.MAX_VALUE+")"); - } - -} diff --git a/src/org/codehaus/jackson/impl/JsonParserBase.java b/src/org/codehaus/jackson/impl/JsonParserBase.java deleted file mode 100644 index cdad3e5565..0000000000 --- a/src/org/codehaus/jackson/impl/JsonParserBase.java +++ /dev/null @@ -1,670 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.util.ByteArrayBuilder; -import org.codehaus.jackson.util.TextBuffer; - -/** - * Intermediate base class used by all Jackson {@link JsonParser} - * implementations. Contains most common things that are independent - * of actual underlying input source - * - * @author Tatu Saloranta - */ -public abstract class JsonParserBase - extends JsonParser -{ - // Control chars: - final static int INT_TAB = '\t'; - final static int INT_LF = '\n'; - final static int INT_CR = '\r'; - final static int INT_SPACE = 0x0020; - - // Markup - final static int INT_LBRACKET = '['; - final static int INT_RBRACKET = ']'; - final static int INT_LCURLY = '{'; - final static int INT_RCURLY = '}'; - final static int INT_QUOTE = '"'; - final static int INT_BACKSLASH = '\\'; - final static int INT_SLASH = '/'; - final static int INT_COLON = ':'; - final static int INT_COMMA = ','; - final static int INT_ASTERISK = '*'; - final static int INT_APOSTROPHE = '\''; - - // Letters we need - final static int INT_b = 'b'; - final static int INT_f = 'f'; - final static int INT_n = 'n'; - final static int INT_r = 'r'; - final static int INT_t = 't'; - final static int INT_u = 'u'; - - /* - //////////////////////////////////////////////////// - // Generic I/O state - //////////////////////////////////////////////////// - */ - - /** - * I/O context for this reader. It handles buffer allocation - * for the reader. - */ - final protected IOContext _ioContext; - - /** - * Flag that indicates whether parser is closed or not. Gets - * set when parser is either closed by explicit call - * ({@link #close}) or when end-of-input is reached. - */ - protected boolean _closed; - - /* - //////////////////////////////////////////////////// - // Current input data - //////////////////////////////////////////////////// - */ - - // Note: type of actual buffer depends on sub-class, can't include - - /** - * Pointer to next available character in buffer - */ - protected int _inputPtr = 0; - - /** - * Index of character after last available one in the buffer. - */ - protected int _inputEnd = 0; - - /* - //////////////////////////////////////////////////// - // Current input location information - //////////////////////////////////////////////////// - */ - - /** - * Number of characters that were contained in previous blocks - * (blocks that were already processed prior to the current buffer). - */ - protected long _currInputProcessed = 0L; - - /** - * Current row location of current point in input buffer, starting - * from 1 - */ - protected int _currInputRow = 1; - - /** - * Current index of the first character of the current row in input - * buffer. Needed to calculate column position, if necessary; benefit - * of not having column itself is that this only has to be updated - * once per line. - */ - protected int _currInputRowStart = 0; - - /* - //////////////////////////////////////////////////// - // Information about starting location of event - // Reader is pointing to; updated on-demand - //////////////////////////////////////////////////// - */ - - // // // Location info at point when current token was started - - /** - * Total number of characters read before start of current token. - * For big (gigabyte-sized) sizes are possible, needs to be long, - * unlike pointers and sizes related to in-memory buffers. - */ - protected long _tokenInputTotal = 0; - - /** - * Input row on which current token starts, 1-based - */ - protected int _tokenInputRow = 1; - - /** - * Column on input row that current token starts; 0-based (although - * in the end it'll be converted to 1-based) - */ - protected int _tokenInputCol = 0; - - /* - //////////////////////////////////////////////////// - // Parsing state - //////////////////////////////////////////////////// - */ - - /** - * Information about parser context, context in which - * the next token is to be parsed (root, array, object). - */ - protected JsonReadContext _parsingContext; - - /** - * Secondary token related to the current token: used when - * the current token is FIELD_NAME but the - * actual value token is also known. - */ - protected JsonToken _nextToken; - - /** - * Flag that indicates that the current token has not yet - * been fully processed, and needs to be finished for - * some access (or skipped to obtain the next token) - */ - protected boolean _tokenIncomplete = false; - - /* - //////////////////////////////////////////////////// - // Buffer(s) for local name(s) and text content - //////////////////////////////////////////////////// - */ - - /** - * Buffer that contains contents of String values, including - * field names if necessary (name split across boundary, - * contains escape sequence, or access needed to char array) - */ - protected final TextBuffer _textBuffer; - - /** - * Temporary buffer that is needed if field name is accessed - * using {@link #getTextCharacters} method (instead of String - * returning alternatives) - */ - protected char[] _nameCopyBuffer = null; - - /** - * Flag set to indicate whether the field name is available - * from the name copy buffer or not (in addition to its String - * representation being available via read context) - */ - protected boolean _nameCopied = false; - - /** - * ByteArrayBuilder is needed if 'getBinaryValue' is called. If so, - * we better reuse it for remainder of content. - */ - ByteArrayBuilder _byteArrayBuilder = null; - - /** - * We will hold on to decoded binary data, for duration of - * current event, so that multiple calls to - * {@link #getBinaryValue} will not need to decode data more - * than once. - */ - protected byte[] _binaryValue; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - protected JsonParserBase(IOContext ctxt, int features) - { - _ioContext = ctxt; - _features = features; - _textBuffer = ctxt.constructTextBuffer(); - _parsingContext = JsonReadContext.createRootContext(_tokenInputRow, _tokenInputCol); - } - - /* - //////////////////////////////////////////////////// - // Configuration overrides if any - //////////////////////////////////////////////////// - */ - - // from base class: - - //public void enableFeature(Feature f) - //public void disableFeature(Feature f) - //public void setFeature(Feature f, boolean state) - //public boolean isFeatureEnabled(Feature f) - - /* - //////////////////////////////////////////////////// - // Abstract methods needed from sub-classes - //////////////////////////////////////////////////// - */ - - protected abstract void _finishString() throws IOException, JsonParseException; - - /* - //////////////////////////////////////////////////// - // JsonParser impl - //////////////////////////////////////////////////// - */ - - public abstract JsonToken nextToken() - throws IOException, JsonParseException; - - //public final JsonToken nextValue() - - public JsonParser skipChildren() - throws IOException, JsonParseException - { - if (_currToken != JsonToken.START_OBJECT - && _currToken != JsonToken.START_ARRAY) { - return this; - } - int open = 1; - - /* Since proper matching of start/end markers is handled - * by nextToken(), we'll just count nesting levels here - */ - while (true) { - JsonToken t = nextToken(); - if (t == null) { - _handleEOF(); - /* given constraints, above should never return; - * however, FindBugs doesn't know about it and - * complains... so let's add dummy break here - */ - return this; - } - switch (t) { - case START_OBJECT: - case START_ARRAY: - ++open; - break; - case END_OBJECT: - case END_ARRAY: - if (--open == 0) { - return this; - } - break; - } - } - } - - //public JsonToken getCurrentToken() - - //public boolean hasCurrentToken() - - /** - * Method that can be called to get the name associated with - * the current event. - */ - public String getCurrentName() - throws IOException, JsonParseException - { - return _parsingContext.getCurrentName(); - } - - public void close() throws IOException - { - _closed = true; - _closeInput(); - // Also, internal buffer(s) can now be released as well - _releaseBuffers(); - } - - public boolean isClosed() { return _closed; } - - public JsonReadContext getParsingContext() - { - return _parsingContext; - } - - /** - * Method that return the starting location of the current - * token; that is, position of the first character from input - * that starts the current token. - */ - public JsonLocation getTokenLocation() - { - return new JsonLocation(_ioContext.getSourceReference(), - getTokenCharacterOffset(), - getTokenLineNr(), - getTokenColumnNr()); - } - - /** - * Method that returns location of the last processed character; - * usually for error reporting purposes - */ - public JsonLocation getCurrentLocation() - { - int col = _inputPtr - _currInputRowStart + 1; // 1-based - return new JsonLocation(_ioContext.getSourceReference(), - _currInputProcessed + _inputPtr - 1, - _currInputRow, col); - } - - /* - //////////////////////////////////////////////////// - // Public API, access to token information, text - //////////////////////////////////////////////////// - */ - - /** - * Method for accessing textual representation of the current event; - * if no current event (before first call to {@link #nextToken}, or - * after encountering end-of-input), returns null. - * Method can be called for any event. - */ - public String getText() - throws IOException, JsonParseException - { - if (_currToken != null) { // null only before/after document - switch (_currToken) { - case FIELD_NAME: - return _parsingContext.getCurrentName(); - - case VALUE_STRING: - if (_tokenIncomplete) { - _tokenIncomplete = false; - _finishString(); // only strings can be incomplete - } - // fall through - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - return _textBuffer.contentsAsString(); - - default: - return _currToken.asString(); - } - } - return null; - } - - public char[] getTextCharacters() - throws IOException, JsonParseException - { - if (_currToken != null) { // null only before/after document - switch (_currToken) { - - case FIELD_NAME: - if (!_nameCopied) { - String name = _parsingContext.getCurrentName(); - int nameLen = name.length(); - if (_nameCopyBuffer == null) { - _nameCopyBuffer = _ioContext.allocNameCopyBuffer(nameLen); - } else if (_nameCopyBuffer.length < nameLen) { - _nameCopyBuffer = new char[nameLen]; - } - name.getChars(0, nameLen, _nameCopyBuffer, 0); - _nameCopied = true; - } - return _nameCopyBuffer; - - case VALUE_STRING: - if (_tokenIncomplete) { - _tokenIncomplete = false; - _finishString(); // only strings can be incomplete - } - // fall through - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - return _textBuffer.getTextBuffer(); - - default: - return _currToken.asCharArray(); - } - } - return null; - } - - public int getTextLength() - throws IOException, JsonParseException - { - if (_currToken != null) { // null only before/after document - switch (_currToken) { - - case FIELD_NAME: - return _parsingContext.getCurrentName().length(); - case VALUE_STRING: - if (_tokenIncomplete) { - _tokenIncomplete = false; - _finishString(); // only strings can be incomplete - } - // fall through - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - return _textBuffer.size(); - - default: - return _currToken.asCharArray().length; - } - } - return 0; - } - - public int getTextOffset() - throws IOException, JsonParseException - { - // Most have offset of 0, only some may have other values: - if (_currToken != null) { - switch (_currToken) { - case FIELD_NAME: - return 0; - case VALUE_STRING: - if (_tokenIncomplete) { - _tokenIncomplete = false; - _finishString(); // only strings can be incomplete - } - // fall through - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - return _textBuffer.getTextOffset(); - } - } - return 0; - } - - /* - //////////////////////////////////////////////////// - // Public API, access to token information, binary - //////////////////////////////////////////////////// - */ - - public final byte[] getBinaryValue(Base64Variant b64variant) - throws IOException, JsonParseException - { - if (_currToken != JsonToken.VALUE_STRING) { - _reportError("Current token ("+_currToken+") not VALUE_STRING, can not access as binary"); - } - /* To ensure that we won't see inconsistent data, better clear up - * state... - */ - if (_tokenIncomplete) { - try { - _binaryValue = _decodeBase64(b64variant); - } catch (IllegalArgumentException iae) { - throw _constructError("Failed to decode VALUE_STRING as base64 ("+b64variant+"): "+iae.getMessage()); - } - /* let's clear incomplete only now; allows for accessing other - * textual content in error cases - */ - _tokenIncomplete = false; - } - return _binaryValue; - } - - protected abstract byte[] _decodeBase64(Base64Variant b64variant) - throws IOException, JsonParseException; - - /* - //////////////////////////////////////////////////// - // Public low-level accessors - //////////////////////////////////////////////////// - */ - - public final long getTokenCharacterOffset() { return _tokenInputTotal; } - public final int getTokenLineNr() { return _tokenInputRow; } - public final int getTokenColumnNr() { return _tokenInputCol+1; } - - /* - //////////////////////////////////////////////////// - // Low-level reading, other - //////////////////////////////////////////////////// - */ - - protected abstract boolean loadMore() throws IOException; - - protected final void loadMoreGuaranteed() - throws IOException - { - if (!loadMore()) { - _reportInvalidEOF(); - } - } - - protected abstract void _closeInput() - throws IOException; - - /** - * Method called to release internal buffers owned by the base reader.This may be called along with - * {@link #_closeInput} (for example, when explicitly closing this reader instance), or separately (if need be). - * - * @throws java.io.IOException Undocumented. - */ - protected void _releaseBuffers() throws IOException - { - _textBuffer.releaseBuffers(); - char[] buf = _nameCopyBuffer; - if (buf != null) { - _nameCopyBuffer = null; - _ioContext.releaseNameCopyBuffer(buf); - } - } - - /** - * Method called when an EOF is encountered between tokens.If so, it may be a legitimate EOF, but only iff there is - * no open non-root context. - * - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _handleEOF() - throws JsonParseException - { - if (!_parsingContext.inRoot()) { - _reportInvalidEOF(": expected close marker for "+_parsingContext.getTypeDesc()+" (from "+_parsingContext.getStartLocation(_ioContext.getSourceReference())+")"); - } - } - - /* - //////////////////////////////////////////////////// - // Error reporting - //////////////////////////////////////////////////// - */ - - protected void _reportUnexpectedChar(int ch, String comment) - throws JsonParseException - { - String msg = "Unexpected character ("+_getCharDesc(ch)+")"; - if (comment != null) { - msg += ": "+comment; - } - _reportError(msg); - } - - protected void _reportInvalidEOF() - throws JsonParseException - { - _reportInvalidEOF(" in "+_currToken); - } - - protected void _reportInvalidEOF(String msg) - throws JsonParseException - { - _reportError("Unexpected end-of-input"+msg); - } - - protected void _throwInvalidSpace(int i) - throws JsonParseException - { - char c = (char) i; - String msg = "Illegal character ("+_getCharDesc(c)+"): only regular white space (\\r, \\n, \\t) is allowed between tokens"; - _reportError(msg); - } - - /** - * Method called to report a problem with unquoted control character.Note: starting with version 1.4, it is possible - * to suppress exception by enabling Feature.ALLOW_UNQUOTED_CONTROL_CHARS. - * - * @param i Undocumented. - * @param ctxtDesc Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _throwUnquotedSpace(int i, String ctxtDesc) - throws JsonParseException - { - // JACKSON-208; possible to allow unquoted control chars: - if (!isEnabled(Feature.ALLOW_UNQUOTED_CONTROL_CHARS) || i >= INT_SPACE) { - char c = (char) i; - String msg = "Illegal unquoted character ("+_getCharDesc(c)+"): has to be escaped using backslash to be included in "+ctxtDesc; - _reportError(msg); - } - } - - protected void _reportMismatchedEndMarker(int actCh, char expCh) - throws JsonParseException - { - String startDesc = ""+_parsingContext.getStartLocation(_ioContext.getSourceReference()); - _reportError("Unexpected close marker '"+((char) actCh)+"': expected '"+expCh+"' (for "+_parsingContext.getTypeDesc()+" starting at "+startDesc+")"); - } - - /* - //////////////////////////////////////////////////// - // Error reporting, generic - //////////////////////////////////////////////////// - */ - - protected final static String _getCharDesc(int ch) - { - char c = (char) ch; - if (Character.isISOControl(c)) { - return "(CTRL-CHAR, code "+ch+")"; - } - if (ch > 255) { - return "'"+c+"' (code "+ch+" / 0x"+Integer.toHexString(ch)+")"; - } - return "'"+c+"' (code "+ch+")"; - } - - protected final void _reportError(String msg) - throws JsonParseException - { - throw _constructError(msg); - } - - protected final void _wrapError(String msg, Throwable t) - throws JsonParseException - { - throw _constructError(msg, t); - } - - protected final void _throwInternal() - { - throw new RuntimeException("Internal error: this code path should never get executed"); - } - - protected final JsonParseException _constructError(String msg, Throwable t) - { - return new JsonParseException(msg, getCurrentLocation(), t); - } - - /* - //////////////////////////////////////////////////// - // Other helper methods for sub-classes - //////////////////////////////////////////////////// - */ - - public ByteArrayBuilder _getByteArrayBuilder() - { - if (_byteArrayBuilder == null) { - _byteArrayBuilder = new ByteArrayBuilder(); - } else { - _byteArrayBuilder.reset(); - } - return _byteArrayBuilder; - } -} diff --git a/src/org/codehaus/jackson/impl/JsonReadContext.java b/src/org/codehaus/jackson/impl/JsonReadContext.java deleted file mode 100644 index 193f6d2635..0000000000 --- a/src/org/codehaus/jackson/impl/JsonReadContext.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.codehaus.jackson.impl; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.util.CharTypes; - -/** - * Extension of {@link JsonStreamContext}, which implements - * core methods needed, and also exposes - * more complete API to parser implementation classes. - */ -public final class JsonReadContext - extends JsonStreamContext -{ - // // // Configuration - - protected final JsonReadContext _parent; - - // // // Location information (minus source reference) - - //long mTotalChars; - - protected int _lineNr; - protected int _columnNr; - - protected String _currentName; - - /* - ////////////////////////////////////////////////// - // Simple instance reuse slots; speeds up things - // a bit (10-15%) for docs with lots of small - // arrays/objects (for which allocation was - // visible in profile stack frames) - ////////////////////////////////////////////////// - */ - - JsonReadContext _child = null; - - /* - ////////////////////////////////////////////////// - // Instance construction, reuse - ////////////////////////////////////////////////// - */ - - public JsonReadContext(JsonReadContext parent, - int type, int lineNr, int colNr) - { - super(type); - _parent = parent; - _lineNr = lineNr; - _columnNr = colNr; - } - - protected final void reset(int type, int lineNr, int colNr) - { - _type = type; - _index = -1; - _lineNr = lineNr; - _columnNr = colNr; - _currentName = null; - } - - // // // Factory methods - - public static JsonReadContext createRootContext(int lineNr, int colNr) - { - return new JsonReadContext(null, TYPE_ROOT, lineNr, colNr); - } - - public final JsonReadContext createChildArrayContext(int lineNr, int colNr) - { - JsonReadContext ctxt = _child; - if (ctxt == null) { - return (_child = new JsonReadContext(this, TYPE_ARRAY, lineNr, colNr)); - } - ctxt.reset(TYPE_ARRAY, lineNr, colNr); - return ctxt; - } - - public final JsonReadContext createChildObjectContext(int lineNr, int colNr) - { - JsonReadContext ctxt = _child; - if (ctxt == null) { - return (_child = new JsonReadContext(this, TYPE_OBJECT, lineNr, colNr)); - } - ctxt.reset(TYPE_OBJECT, lineNr, colNr); - return ctxt; - } - - /* - ////////////////////////////////////////////////// - // Abstract method implementation - ////////////////////////////////////////////////// - */ - - public final String getCurrentName() { return _currentName; } - - public final JsonReadContext getParent() { return _parent; } - - /* - ////////////////////////////////////////////////// - // Extended API - ////////////////////////////////////////////////// - */ - - /** - * @param srcRef Undocumented. - * @return Location pointing to the point where the context - * start marker was found - */ - public final JsonLocation getStartLocation(Object srcRef) - { - /* We don't keep track of offsets at this level (only - * reader does) - */ - long totalChars = -1L; - - return new JsonLocation(srcRef, totalChars, _lineNr, _columnNr); - } - - /* - ////////////////////////////////////////////////// - // State changes - ////////////////////////////////////////////////// - */ - - public final boolean expectComma() - { - /* Assumption here is that we will be getting a value (at least - * before calling this method again), and - * so will auto-increment index to avoid having to do another call - */ - int ix = ++_index; // starts from -1 - return (_type != TYPE_ROOT && ix > 0); - } - - public void setCurrentName(String name) - { - _currentName = name; - } - - /* - ////////////////////////////////////////////////// - // Overridden standard methods - ////////////////////////////////////////////////// - */ - - /** - * Overridden to provide developer readable "JsonPath" representation - * of the context. - */ - public final String toString() - { - StringBuilder sb = new StringBuilder(64); - switch (_type) { - case TYPE_ROOT: - sb.append("/"); - break; - case TYPE_ARRAY: - sb.append('['); - sb.append(getCurrentIndex()); - sb.append(']'); - break; - case TYPE_OBJECT: - sb.append('{'); - if (_currentName != null) { - sb.append('"'); - CharTypes.appendQuoted(sb, _currentName); - sb.append('"'); - } else { - sb.append('?'); - } - sb.append(']'); - break; - } - return sb.toString(); - } -} diff --git a/src/org/codehaus/jackson/impl/JsonWriteContext.java b/src/org/codehaus/jackson/impl/JsonWriteContext.java deleted file mode 100644 index 63558ac23f..0000000000 --- a/src/org/codehaus/jackson/impl/JsonWriteContext.java +++ /dev/null @@ -1,229 +0,0 @@ -package org.codehaus.jackson.impl; - -import org.codehaus.jackson.*; - -/** - * Extension of {@link JsonStreamContext}, which implements - * core methods needed, and also exposes - * more complete API to generator implementation classes. - */ -public abstract class JsonWriteContext - extends JsonStreamContext -{ - // // // Return values for writeValue() - - public final static int STATUS_OK_AS_IS = 0; - public final static int STATUS_OK_AFTER_COMMA = 1; - public final static int STATUS_OK_AFTER_COLON = 2; - public final static int STATUS_OK_AFTER_SPACE = 3; // in root context - public final static int STATUS_EXPECT_VALUE = 4; - public final static int STATUS_EXPECT_NAME = 5; - - protected final JsonWriteContext _parent; - - /* - ////////////////////////////////////////////////// - // Simple instance reuse slots; speed up things - // a bit (10-15%) for docs with lots of small - // arrays/objects - ////////////////////////////////////////////////// - */ - - JsonWriteContext _childArray = null; - - JsonWriteContext _childObject = null; - - /* - ////////////////////////////////////////////////// - // Life-cycle - ////////////////////////////////////////////////// - */ - - protected JsonWriteContext(int type, JsonWriteContext parent) - { - super(type); - _parent = parent; - } - - // // // Factory methods - - public static JsonWriteContext createRootContext() - { - return new RootWContext(); - } - - public final JsonWriteContext createChildArrayContext() - { - JsonWriteContext ctxt = _childArray; - if (ctxt == null) { - _childArray = ctxt = new ArrayWContext(this); - } else { // need to reset settings; parent is already ok - ctxt._index = -1; - } - return ctxt; - } - - public final JsonWriteContext createChildObjectContext() - { - JsonWriteContext ctxt = _childObject; - if (ctxt == null) { - _childObject = ctxt = new ObjectWContext(this); - } else { // need to reset settings; parent is already ok - ctxt._index = -1; - } - return ctxt; - } - - // // // Shared API - - public final JsonWriteContext getParent() { return _parent; } - - // // // API sub-classes are to implement - - /** - * Method that writer is to call before it writes a field name. - * - * @param name Undocumented. - * @return Index of the field entry (0-based) - */ - public abstract int writeFieldName(String name); - - public abstract int writeValue(); - - // // // Internally used abstract methods - - protected abstract void appendDesc(StringBuilder sb); - - // // // Overridden standard methods - - /** - * Overridden to provide developer writeable "JsonPath" representation - * of the context. - */ - public final String toString() - { - StringBuilder sb = new StringBuilder(64); - appendDesc(sb); - return sb.toString(); - } -} - -/** - * Root context is simple, as only state it keeps is the index of - * the currently active entry. - */ -final class RootWContext - extends JsonWriteContext -{ - public RootWContext() - { - super(TYPE_ROOT, null); - } - - public String getCurrentName() { return null; } - - public int writeFieldName(String name) - { - return STATUS_EXPECT_VALUE; - } - - public int writeValue() - { - // No commas within root context, but need space - ++_index; - return (_index == 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_SPACE; - } - - protected void appendDesc(StringBuilder sb) - { - sb.append("/"); - } -} - -final class ArrayWContext - extends JsonWriteContext -{ - public ArrayWContext(JsonWriteContext parent) - { - super(TYPE_ARRAY, parent); - } - - public String getCurrentName() { return null; } - - public int writeFieldName(String name) - { - return STATUS_EXPECT_VALUE; - } - - public int writeValue() - { - int ix = _index; - ++_index; - return (ix < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA; - } - - protected void appendDesc(StringBuilder sb) - { - sb.append('['); - sb.append(getCurrentIndex()); - sb.append(']'); - } -} - -final class ObjectWContext - extends JsonWriteContext -{ - /** - * Name of the field of which value is to be parsed. - */ - protected String _currentName; - - /** - * Flag to indicate that the context just received the - * field name, and is to get a value next - */ - protected boolean _expectValue; - - public ObjectWContext(JsonWriteContext parent) - { - super(TYPE_OBJECT, parent); - _currentName = null; - _expectValue = false; - } - - public String getCurrentName() { return _currentName; } - - public int writeFieldName(String name) - { - if (_currentName != null) { // just wrote a name... - return STATUS_EXPECT_VALUE; - } - _currentName = name; - return (_index < 0) ? STATUS_OK_AS_IS : STATUS_OK_AFTER_COMMA; - } - - public int writeValue() - { - if (_currentName == null) { - return STATUS_EXPECT_NAME; - } - _currentName = null; - ++_index; - return STATUS_OK_AFTER_COLON; - } - - protected void appendDesc(StringBuilder sb) - { - sb.append('{'); - if (_currentName != null) { - sb.append('"'); - // !!! TODO: Name chars should be escaped? - sb.append(_currentName); - sb.append('"'); - } else { - sb.append('?'); - } - sb.append(']'); - } -} - diff --git a/src/org/codehaus/jackson/impl/ReaderBasedNumericParser.java b/src/org/codehaus/jackson/impl/ReaderBasedNumericParser.java deleted file mode 100644 index d55fea62bc..0000000000 --- a/src/org/codehaus/jackson/impl/ReaderBasedNumericParser.java +++ /dev/null @@ -1,302 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.IOException; -import java.io.Reader; - -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonToken; - -/** - * Intermediate class that implements handling of numeric parsing. - * Separate from the actual parser class just to isolate numeric - * parsing: would be nice to use aggregation, but unfortunately - * many parts are hard to implement without direct access to - * underlying buffers. - */ -public abstract class ReaderBasedNumericParser - extends ReaderBasedParserBase -{ - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - public ReaderBasedNumericParser(IOContext pc, int features, Reader r) - { - super(pc, features, r); - } - - /* - //////////////////////////////////////////////////// - // Textual parsing of number values - //////////////////////////////////////////////////// - */ - - /** - * Initial parsing method for number values. It needs to be able - * to parse enough input to be able to determine whether the - * value is to be considered a simple integer value, or a more - * generic decimal value: latter of which needs to be expressed - * as a floating point number. The basic rule is that if the number - * has no fractional or exponential part, it is an integer; otherwise - * a floating point number. - *

- * Because much of input has to be processed in any case, no partial - * parsing is done: all input text will be stored for further - * processing. However, actual numeric value conversion will be - * deferred, since it is usually the most complicated and costliest - * part of processing. - */ - @Override - protected final JsonToken parseNumberText(int ch) - throws IOException, JsonParseException - { - /* Although we will always be complete with respect to textual - * representation (that is, all characters will be parsed), - * actual conversion to a number is deferred. Thus, need to - * note that no representations are valid yet - */ - boolean negative = (ch == INT_MINUS); - int ptr = _inputPtr; - int startPtr = ptr-1; // to include sign/digit already read - final int inputLen = _inputEnd; - - dummy_loop: - do { // dummy loop, to be able to break out - if (negative) { // need to read the next digit - if (ptr >= _inputEnd) { - break dummy_loop; - } - ch = _inputBuffer[ptr++]; - // First check: must have a digit to follow minus sign - if (ch > INT_9 || ch < INT_0) { - reportUnexpectedNumberChar(ch, "expected digit (0-9) to follow minus sign, for valid numeric value"); - } - /* (note: has been checked for non-negative already, in - * the dispatching code that determined it should be - * a numeric value) - */ - } - - /* First, let's see if the whole number is contained within - * the input buffer unsplit. This should be the common case; - * and to simplify processing, we will just reparse contents - * in the alternative case (number split on buffer boundary) - */ - - int intLen = 1; // already got one - - // First let's get the obligatory integer part: - - int_loop: - while (true) { - if (ptr >= _inputEnd) { - break dummy_loop; - } - ch = (int) _inputBuffer[ptr++]; - if (ch < INT_0 || ch > INT_9) { - break int_loop; - } - // The only check: no leading zeroes - if (++intLen == 2) { // To ensure no leading zeroes - if (_inputBuffer[ptr-2] == '0') { - reportInvalidNumber("Leading zeroes not allowed"); - } - } - } - - int fractLen = 0; - - // And then see if we get other parts - if (ch == INT_DECIMAL_POINT) { // yes, fraction - fract_loop: - while (true) { - if (ptr >= inputLen) { - break dummy_loop; - } - ch = (int) _inputBuffer[ptr++]; - if (ch < INT_0 || ch > INT_9) { - break fract_loop; - } - ++fractLen; - } - // must be followed by sequence of ints, one minimum - if (fractLen == 0) { - reportUnexpectedNumberChar(ch, "Decimal point not followed by a digit"); - } - } - - int expLen = 0; - if (ch == INT_e || ch == INT_E) { // and/or expontent - if (ptr >= inputLen) { - break dummy_loop; - } - // Sign indicator? - ch = (int) _inputBuffer[ptr++]; - if (ch == INT_MINUS || ch == INT_PLUS) { // yup, skip for now - if (ptr >= inputLen) { - break dummy_loop; - } - ch = (int) _inputBuffer[ptr++]; - } - while (ch <= INT_9 && ch >= INT_0) { - ++expLen; - if (ptr >= inputLen) { - break dummy_loop; - } - ch = (int) _inputBuffer[ptr++]; - } - // must be followed by sequence of ints, one minimum - if (expLen == 0) { - reportUnexpectedNumberChar(ch, "Exponent indicator not followed by a digit"); - } - } - - // Got it all: let's add to text buffer for parsing, access - --ptr; // need to push back following separator - _inputPtr = ptr; - int len = ptr-startPtr; - _textBuffer.resetWithShared(_inputBuffer, startPtr, len); - return reset(negative, intLen, fractLen, expLen); - } while (false); - - _inputPtr = negative ? (startPtr+1) : startPtr; - return parseNumberText2(negative); - } - - /** - * Method called to parse a number, when the primary parse - * method has failed to parse it, due to it being split on - * buffer boundary. As a result code is very similar, except - * that it has to explicitly copy contents to the text buffer - * instead of just sharing the main input buffer. - */ - private final JsonToken parseNumberText2(boolean negative) - throws IOException, JsonParseException - { - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - int outPtr = 0; - - // Need to prepend sign? - if (negative) { - outBuf[outPtr++] = '-'; - } - - char c; - int intLen = 0; - boolean eof = false; - - // Ok, first the obligatory integer part: - int_loop: - while (true) { - if (_inputPtr >= _inputEnd && !loadMore()) { - // EOF is legal for main level int values - c = CHAR_NULL; - eof = true; - break int_loop; - } - c = _inputBuffer[_inputPtr++]; - if (c < INT_0 || c > INT_9) { - break int_loop; - } - ++intLen; - // Quickie check: no leading zeroes allowed - if (intLen == 2) { - if (outBuf[outPtr-1] == '0') { - reportInvalidNumber("Leading zeroes not allowed"); - } - } - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = c; - } - // Also, integer part is not optional - if (intLen == 0) { - reportInvalidNumber("Missing integer part (next char "+_getCharDesc(c)+")"); - } - - int fractLen = 0; - // And then see if we get other parts - if (c == '.') { // yes, fraction - outBuf[outPtr++] = c; - - fract_loop: - while (true) { - if (_inputPtr >= _inputEnd && !loadMore()) { - eof = true; - break fract_loop; - } - c = _inputBuffer[_inputPtr++]; - if (c < INT_0 || c > INT_9) { - break fract_loop; - } - ++fractLen; - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = c; - } - // must be followed by sequence of ints, one minimum - if (fractLen == 0) { - reportUnexpectedNumberChar(c, "Decimal point not followed by a digit"); - } - } - - int expLen = 0; - if (c == 'e' || c == 'E') { // exponent? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = c; - // Not optional, can require that we get one more char - c = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] - : getNextChar("expected a digit for number exponent"); - // Sign indicator? - if (c == '-' || c == '+') { - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = c; - // Likewise, non optional: - c = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] - : getNextChar("expected a digit for number exponent"); - } - - exp_loop: - while (c <= INT_9 && c >= INT_0) { - ++expLen; - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = c; - if (_inputPtr >= _inputEnd && !loadMore()) { - eof = true; - break exp_loop; - } - c = _inputBuffer[_inputPtr++]; - } - // must be followed by sequence of ints, one minimum - if (expLen == 0) { - reportUnexpectedNumberChar(c, "Exponent indicator not followed by a digit"); - } - } - - // Ok; unless we hit end-of-input, need to push last char read back - if (!eof) { - --_inputPtr; - } - _textBuffer.setCurrentLength(outPtr); - - // And there we have it! - return reset(negative, intLen, fractLen, expLen); - } - -} diff --git a/src/org/codehaus/jackson/impl/ReaderBasedParser.java b/src/org/codehaus/jackson/impl/ReaderBasedParser.java deleted file mode 100644 index 0311f9c044..0000000000 --- a/src/org/codehaus/jackson/impl/ReaderBasedParser.java +++ /dev/null @@ -1,1056 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.sym.CharsToNameCanonicalizer; -import org.codehaus.jackson.util.*; - -/** - * This is a concrete implementation of {@link JsonParser}, which is - * based on a {@link java.io.Reader} to handle low-level character - * conversion tasks. - */ -public final class ReaderBasedParser - extends ReaderBasedNumericParser -{ - /* - /*************************************************** - /* Configuration, state - /*************************************************** - */ - - protected ObjectCodec _objectCodec; - - final protected CharsToNameCanonicalizer _symbols; - - /* - /*************************************************** - /* Life-cycle - /*************************************************** - */ - - public ReaderBasedParser(IOContext ioCtxt, int features, Reader r, - ObjectCodec codec, CharsToNameCanonicalizer st) - { - super(ioCtxt, features, r); - _objectCodec = codec; - _symbols = st; - } - - public ObjectCodec getCodec() { - return _objectCodec; - } - - public void setCodec(ObjectCodec c) { - _objectCodec = c; - } - - /* - /*************************************************** - /* Public API, traversal - /*************************************************** - */ - - /** - * @return Next token from the stream, if any found, or null - * to indicate end-of-input - */ - @Override - public JsonToken nextToken() - throws IOException, JsonParseException - { - /* First: field names are special -- we will always tokenize - * (part of) value along with field name to simplify - * state handling. If so, can and need to use secondary token: - */ - if (_currToken == JsonToken.FIELD_NAME) { - return _nextAfterName(); - } - if (_tokenIncomplete) { - _skipString(); // only strings can be partial - } - - int i = _skipWSOrEnd(); - if (i < 0) { // end-of-input - /* 19-Feb-2009, tatu: Should actually close/release things - * like input source, symbol table and recyclable buffers now. - */ - close(); - return (_currToken = null); - } - - /* First, need to ensure we know the starting location of token - * after skipping leading white space - */ - _tokenInputTotal = _currInputProcessed + _inputPtr - 1; - _tokenInputRow = _currInputRow; - _tokenInputCol = _inputPtr - _currInputRowStart - 1; - - // finally: clear any data retained so far - _binaryValue = null; - - // Closing scope? - if (i == INT_RBRACKET) { - if (!_parsingContext.inArray()) { - _reportMismatchedEndMarker(i, '}'); - } - _parsingContext = _parsingContext.getParent(); - return (_currToken = JsonToken.END_ARRAY); - } - if (i == INT_RCURLY) { - if (!_parsingContext.inObject()) { - _reportMismatchedEndMarker(i, ']'); - } - _parsingContext = _parsingContext.getParent(); - return (_currToken = JsonToken.END_OBJECT); - } - - // Nope: do we then expect a comma? - if (_parsingContext.expectComma()) { - if (i != INT_COMMA) { - _reportUnexpectedChar(i, "was expecting comma to separate "+_parsingContext.getTypeDesc()+" entries"); - } - i = _skipWS(); - } - - /* And should we now have a name? Always true for - * Object contexts, since the intermediate 'expect-value' - * state is never retained. - */ - boolean inObject = _parsingContext.inObject(); - if (inObject) { - // First, field name itself: - String name = _parseFieldName(i); - _parsingContext.setCurrentName(name); - _currToken = JsonToken.FIELD_NAME; - i = _skipWS(); - if (i != INT_COLON) { - _reportUnexpectedChar(i, "was expecting a colon to separate field name and value"); - } - i = _skipWS(); - } - - // Ok: we must have a value... what is it? - - JsonToken t; - - switch (i) { - case INT_QUOTE: - _tokenIncomplete = true; - t = JsonToken.VALUE_STRING; - break; - case INT_LBRACKET: - if (!inObject) { - _parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol); - } - t = JsonToken.START_ARRAY; - break; - case INT_LCURLY: - if (!inObject) { - _parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol); - } - t = JsonToken.START_OBJECT; - break; - case INT_RBRACKET: - case INT_RCURLY: - // Error: neither is valid at this point; valid closers have - // been handled earlier - _reportUnexpectedChar(i, "expected a value"); - case INT_t: - _matchToken(JsonToken.VALUE_TRUE); - t = JsonToken.VALUE_TRUE; - break; - case INT_f: - _matchToken(JsonToken.VALUE_FALSE); - t = JsonToken.VALUE_FALSE; - break; - case INT_n: - _matchToken(JsonToken.VALUE_NULL); - t = JsonToken.VALUE_NULL; - break; - - case INT_MINUS: - /* Should we have separate handling for plus? Although - * it is not allowed per se, it may be erroneously used, - * and could be indicate by a more specific error message. - */ - case INT_0: - case INT_1: - case INT_2: - case INT_3: - case INT_4: - case INT_5: - case INT_6: - case INT_7: - case INT_8: - case INT_9: - t = parseNumberText(i); - break; - default: - t = _handleUnexpectedValue(i); - break; - } - - if (inObject) { - _nextToken = t; - return _currToken; - } - _currToken = t; - return t; - } - - private final JsonToken _nextAfterName() - { - _nameCopied = false; // need to invalidate if it was copied - JsonToken t = _nextToken; - _nextToken = null; - // Also: may need to start new context? - if (t == JsonToken.START_ARRAY) { - _parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol); - } else if (t == JsonToken.START_OBJECT) { - _parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol); - } - return (_currToken = t); - } - - @Override - public void close() throws IOException - { - super.close(); - _symbols.release(); - } - - /* - /*************************************************** - /* Internal methods, secondary parsing - /*************************************************** - */ - - protected final String _parseFieldName(int i) - throws IOException, JsonParseException - { - if (i != INT_QUOTE) { - return _handleUnusualFieldName(i); - } - /* First: let's try to see if we have a simple name: one that does - * not cross input buffer boundary, and does not contain escape - * sequences. - */ - int ptr = _inputPtr; - int hash = 0; - final int inputLen = _inputEnd; - - if (ptr < inputLen) { - final int[] codes = CharTypes.getInputCodeLatin1(); - final int maxCode = codes.length; - - do { - int ch = _inputBuffer[ptr]; - if (ch < maxCode && codes[ch] != 0) { - if (ch == '"') { - int start = _inputPtr; - _inputPtr = ptr+1; // to skip the quote - return _symbols.findSymbol(_inputBuffer, start, ptr - start, hash); - } - break; - } - hash = (hash * 31) + ch; - ++ptr; - } while (ptr < inputLen); - } - - int start = _inputPtr; - _inputPtr = ptr; - return _parseFieldName2(start, hash, INT_QUOTE); - } - - private String _parseFieldName2(int startPtr, int hash, int endChar) - throws IOException, JsonParseException - { - _textBuffer.resetWithShared(_inputBuffer, startPtr, (_inputPtr - startPtr)); - - /* Output pointers; calls will also ensure that the buffer is - * not shared and has room for at least one more char. - */ - char[] outBuf = _textBuffer.getCurrentSegment(); - int outPtr = _textBuffer.getCurrentSegmentSize(); - - while (true) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing '"+((char) endChar)+"' for name"); - } - } - char c = _inputBuffer[_inputPtr++]; - int i = (int) c; - if (i <= INT_BACKSLASH) { - if (i == INT_BACKSLASH) { - /* Although chars outside of BMP are to be escaped as - * an UTF-16 surrogate pair, does that affect decoding? - * For now let's assume it does not. - */ - c = _decodeEscaped(); - } else if (i <= endChar) { - if (i == endChar) { - break; - } - if (i < INT_SPACE) { - _throwUnquotedSpace(i, "name"); - } - } - } - hash = (hash * 31) + i; - // Ok, let's add char to output: - outBuf[outPtr++] = c; - - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - } - _textBuffer.setCurrentLength(outPtr); - { - TextBuffer tb = _textBuffer; - char[] buf = tb.getTextBuffer(); - int start = tb.getTextOffset(); - int len = tb.size(); - - return _symbols.findSymbol(buf, start, len, hash); - } - } - - /** - * Method called when we see non-white space character other than double quote, when expecting a field name.In - * standard mode will just throw an expection; but in non-standard modes may be able to parse name. - * - * @param i Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * @since 1.2 - */ - protected final String _handleUnusualFieldName(int i) - throws IOException, JsonParseException - { - // [JACKSON-173]: allow single quotes - if (i == INT_APOSTROPHE && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { - return _parseApostropheFieldName(); - } - // [JACKSON-69]: allow unquoted names if feature enabled: - if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { - _reportUnexpectedChar(i, "was expecting double-quote to start field name"); - } - final int[] codes = CharTypes.getInputCodeLatin1JsNames(); - final int maxCode = codes.length; - - // Also: first char must be a valid name char, but NOT be number - boolean firstOk; - - if (i < maxCode) { // identifier, and not a number - firstOk = (codes[i] == 0) && (i < INT_0 || i > INT_9); - } else { - firstOk = Character.isJavaIdentifierPart((char) i); - } - if (!firstOk) { - _reportUnexpectedChar(i, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); - } - int ptr = _inputPtr; - int hash = 0; - final int inputLen = _inputEnd; - - if (ptr < inputLen) { - do { - int ch = _inputBuffer[ptr]; - if (ch < maxCode) { - if (codes[ch] != 0) { - int start = _inputPtr-1; // -1 to bring back first char - _inputPtr = ptr; - return _symbols.findSymbol(_inputBuffer, start, ptr - start, hash); - } - } else if (!Character.isJavaIdentifierPart((char) ch)) { - int start = _inputPtr-1; // -1 to bring back first char - _inputPtr = ptr; - return _symbols.findSymbol(_inputBuffer, start, ptr - start, hash); - } - hash = (hash * 31) + ch; - ++ptr; - } while (ptr < inputLen); - } - int start = _inputPtr-1; - _inputPtr = ptr; - return _parseUnusualFieldName2(start, hash, codes); - } - - protected final String _parseApostropheFieldName() - throws IOException, JsonParseException - { - // Note: mostly copy of_parseFieldName - int ptr = _inputPtr; - int hash = 0; - final int inputLen = _inputEnd; - - if (ptr < inputLen) { - final int[] codes = CharTypes.getInputCodeLatin1(); - final int maxCode = codes.length; - - do { - int ch = _inputBuffer[ptr]; - if (ch == '\'') { - int start = _inputPtr; - _inputPtr = ptr+1; // to skip the quote - return _symbols.findSymbol(_inputBuffer, start, ptr - start, hash); - } - if (ch < maxCode && codes[ch] != 0) { - break; - } - hash = (hash * 31) + ch; - ++ptr; - } while (ptr < inputLen); - } - - int start = _inputPtr; - _inputPtr = ptr; - - return _parseFieldName2(start, hash, INT_APOSTROPHE); - } - - /** - * Method for handling cases where first non-space character - * of an expected value token is not legal for standard JSON content. - * - * @param i Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * @since 1.3 - */ - protected final JsonToken _handleUnexpectedValue(int i) - throws IOException, JsonParseException - { - // Most likely an error, unless we are to allow single-quote-strings - if (i != INT_APOSTROPHE || !isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { - _reportUnexpectedChar(i, "expected a valid value (number, String, array, object, 'true', 'false' or 'null')"); - } - - /* [JACKSON-173]: allow single quotes. Unlike with regular - * Strings, we'll eagerly parse contents; this so that there's - * no need to store information on quote char used. - * - * Also, no separation to fast/slow parsing; we'll just do - * one regular (~= slow) parsing, to keep code simple - */ - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - int outPtr = _textBuffer.getCurrentSegmentSize(); - - while (true) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing quote for a string value"); - } - } - char c = _inputBuffer[_inputPtr++]; - i = (int) c; - if (i <= INT_BACKSLASH) { - if (i == INT_BACKSLASH) { - /* Although chars outside of BMP are to be escaped as - * an UTF-16 surrogate pair, does that affect decoding? - * For now let's assume it does not. - */ - c = _decodeEscaped(); - } else if (i <= INT_APOSTROPHE) { - if (i == INT_APOSTROPHE) { - break; - } - if (i < INT_SPACE) { - _throwUnquotedSpace(i, "string value"); - } - } - } - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - // Ok, let's add char to output: - outBuf[outPtr++] = c; - } - _textBuffer.setCurrentLength(outPtr); - return JsonToken.VALUE_STRING; - } - - /** - * @since 1.2 - */ - private String _parseUnusualFieldName2(int startPtr, int hash, int[] codes) - throws IOException, JsonParseException - { - _textBuffer.resetWithShared(_inputBuffer, startPtr, (_inputPtr - startPtr)); - char[] outBuf = _textBuffer.getCurrentSegment(); - int outPtr = _textBuffer.getCurrentSegmentSize(); - final int maxCode = codes.length; - - while (true) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { // acceptable for now (will error out later) - break; - } - } - char c = _inputBuffer[_inputPtr]; - int i = (int) c; - if (i <= maxCode) { - if (codes[i] != 0) { - break; - } - } else if (!Character.isJavaIdentifierPart(c)) { - break; - } - ++_inputPtr; - hash = (hash * 31) + i; - // Ok, let's add char to output: - outBuf[outPtr++] = c; - - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - } - _textBuffer.setCurrentLength(outPtr); - { - TextBuffer tb = _textBuffer; - char[] buf = tb.getTextBuffer(); - int start = tb.getTextOffset(); - int len = tb.size(); - - return _symbols.findSymbol(buf, start, len, hash); - } - } - - @Override - protected void _finishString() - throws IOException, JsonParseException - { - /* First: let's try to see if we have simple String value: one - * that does not cross input buffer boundary, and does not - * contain escape sequences. - */ - int ptr = _inputPtr; - final int inputLen = _inputEnd; - - if (ptr < inputLen) { - final int[] codes = CharTypes.getInputCodeLatin1(); - final int maxCode = codes.length; - - do { - int ch = _inputBuffer[ptr]; - if (ch < maxCode && codes[ch] != 0) { - if (ch == '"') { - _textBuffer.resetWithShared(_inputBuffer, _inputPtr, (ptr-_inputPtr)); - _inputPtr = ptr+1; - // Yes, we got it all - return; - } - break; - } - ++ptr; - } while (ptr < inputLen); - } - - /* Either ran out of input, or bumped into an escape - * sequence... - */ - _textBuffer.resetWithCopy(_inputBuffer, _inputPtr, (ptr-_inputPtr)); - _inputPtr = ptr; - _finishString2(); - } - - protected void _finishString2() - throws IOException, JsonParseException - { - char[] outBuf = _textBuffer.getCurrentSegment(); - int outPtr = _textBuffer.getCurrentSegmentSize(); - - while (true) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing quote for a string value"); - } - } - char c = _inputBuffer[_inputPtr++]; - int i = (int) c; - if (i <= INT_BACKSLASH) { - if (i == INT_BACKSLASH) { - /* Although chars outside of BMP are to be escaped as - * an UTF-16 surrogate pair, does that affect decoding? - * For now let's assume it does not. - */ - c = _decodeEscaped(); - } else if (i <= INT_QUOTE) { - if (i == INT_QUOTE) { - break; - } - if (i < INT_SPACE) { - _throwUnquotedSpace(i, "string value"); - } - } - } - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - // Ok, let's add char to output: - outBuf[outPtr++] = c; - } - _textBuffer.setCurrentLength(outPtr); - } - - /** - * Method called to skim through rest of unparsed String value, if it is not needed.This can be done bit faster if - * contents need not be stored for future access. - * - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _skipString() - throws IOException, JsonParseException - { - _tokenIncomplete = false; - - int inputPtr = _inputPtr; - int inputLen = _inputEnd; - char[] inputBuffer = _inputBuffer; - - while (true) { - if (inputPtr >= inputLen) { - _inputPtr = inputPtr; - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing quote for a string value"); - } - inputPtr = _inputPtr; - inputLen = _inputEnd; - } - char c = inputBuffer[inputPtr++]; - int i = (int) c; - if (i <= INT_BACKSLASH) { - if (i == INT_BACKSLASH) { - /* Although chars outside of BMP are to be escaped as - * an UTF-16 surrogate pair, does that affect decoding? - * For now let's assume it does not. - */ - _inputPtr = inputPtr; - c = _decodeEscaped(); - inputPtr = _inputPtr; - inputLen = _inputEnd; - } else if (i <= INT_QUOTE) { - if (i == INT_QUOTE) { - _inputPtr = inputPtr; - break; - } - if (i < INT_SPACE) { - _inputPtr = inputPtr; - _throwUnquotedSpace(i, "string value"); - } - } - } - } - } - - /** - * Method called to much one of literal tokens we may expect - * @param token Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _matchToken(JsonToken token) - throws IOException, JsonParseException - { - // First char is already matched, need to check the rest - String matchStr = token.asString(); - int i = 1; - - for (int len = matchStr.length(); i < len; ++i) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in a value"); - } - } - char c = _inputBuffer[_inputPtr]; - if (c != matchStr.charAt(i)) { - _reportInvalidToken(matchStr.substring(0, i)); - } - ++_inputPtr; - } - /* Ok, fine; let's not bother checking anything beyond keyword. - * If there's something wrong there, it'll cause a parsing - * error later on. - */ - return; - } - - private void _reportInvalidToken(String matchedPart) - throws IOException, JsonParseException - { - StringBuilder sb = new StringBuilder(matchedPart); - /* Let's just try to find what appears to be the token, using - * regular Java identifier character rules. It's just a heuristic, - * nothing fancy here. - */ - while (true) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - break; - } - } - char c = _inputBuffer[_inputPtr]; - if (!Character.isJavaIdentifierPart(c)) { - break; - } - ++_inputPtr; - sb.append(c); - } - - _reportError("Unrecognized token '"+sb.toString()+"': was expecting 'null', 'true' or 'false'"); - } - - /* - /*************************************************** - /* Internal methods, other parsing - /*************************************************** - */ - - /** - * We actually need to check the character value here - * (to see if we have \n following \r). - * @throws java.io.IOException Undocumented. - */ - protected final void _skipCR() throws IOException - { - if (_inputPtr < _inputEnd || loadMore()) { - if (_inputBuffer[_inputPtr] == '\n') { - ++_inputPtr; - } - } - ++_currInputRow; - _currInputRowStart = _inputPtr; - } - - protected final void _skipLF() throws IOException - { - ++_currInputRow; - _currInputRowStart = _inputPtr; - } - - private final int _skipWS() - throws IOException, JsonParseException - { - while (_inputPtr < _inputEnd || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++]; - if (i > INT_SPACE) { - if (i != INT_SLASH) { - return i; - } - _skipComment(); - } else if (i != INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - } else if (i == INT_CR) { - _skipCR(); - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - throw _constructError("Unexpected end-of-input within/between "+_parsingContext.getTypeDesc()+" entries"); - } - - private final int _skipWSOrEnd() - throws IOException, JsonParseException - { - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++]; - if (i > INT_SPACE) { - if (i != INT_SLASH) { - return i; - } - _skipComment(); - } else if (i != INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - } else if (i == INT_CR) { - _skipCR(); - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - // We ran out of input... - _handleEOF(); - return -1; - } - - private final void _skipComment() - throws IOException, JsonParseException - { - if (!isEnabled(Feature.ALLOW_COMMENTS)) { - _reportUnexpectedChar('/', "maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser)"); - } - // First: check which comment (if either) it is: - if (_inputPtr >= _inputEnd && !loadMore()) { - _reportInvalidEOF(" in a comment"); - } - char c = _inputBuffer[_inputPtr++]; - if (c == '/') { - _skipCppComment(); - } else if (c == '*') { - _skipCComment(); - } else { - _reportUnexpectedChar(c, "was expecting either '*' or '/' for a comment"); - } - } - - private final void _skipCComment() - throws IOException, JsonParseException - { - // Ok: need the matching '*/' - main_loop: - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++]; - if (i <= INT_ASTERISK) { - if (i == INT_ASTERISK) { // end? - if ((_inputPtr >= _inputEnd) && !loadMore()) { - break main_loop; - } - if (_inputBuffer[_inputPtr] == INT_SLASH) { - ++_inputPtr; - return; - } - continue; - } - if (i < INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - } else if (i == INT_CR) { - _skipCR(); - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - } - _reportInvalidEOF(" in a comment"); - } - - private final void _skipCppComment() - throws IOException, JsonParseException - { - // Ok: need to find EOF or linefeed - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++]; - if (i < INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - break; - } else if (i == INT_CR) { - _skipCR(); - break; - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - } - - protected final char _decodeEscaped() - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in character escape sequence"); - } - } - char c = _inputBuffer[_inputPtr++]; - - switch ((int) c) { - // First, ones that are mapped - case INT_b: - return '\b'; - case INT_t: - return '\t'; - case INT_n: - return '\n'; - case INT_f: - return '\f'; - case INT_r: - return '\r'; - - // And these are to be returned as they are - case INT_QUOTE: - case INT_SLASH: - case INT_BACKSLASH: - return c; - - case INT_u: // and finally hex-escaped - break; - - default: - _reportError("Unrecognized character escape "+_getCharDesc(c)); - } - - // Ok, a hex escape. Need 4 characters - int value = 0; - for (int i = 0; i < 4; ++i) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in character escape sequence"); - } - } - int ch = (int) _inputBuffer[_inputPtr++]; - int digit = CharTypes.charToHex(ch); - if (digit < 0) { - _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); - } - value = (value << 4) | digit; - } - return (char) value; - } - - /* - /*************************************************** - /* Binary access - /*************************************************** - */ - - @Override - protected byte[] _decodeBase64(Base64Variant b64variant) - throws IOException, JsonParseException - { - ByteArrayBuilder builder = _getByteArrayBuilder(); - - /* !!! 23-Jan-2009, tatu: There are some potential problems - * with this: - * - * - Escaped chars are not handled. Should they? - */ - - //main_loop: - while (true) { - // first, we'll skip preceding white space, if any - char ch; - do { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++]; - } while (ch <= INT_SPACE); - int bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { // reached the end, fair and square? - if (ch == '"') { - return builder.toByteArray(); - } - throw reportInvalidChar(b64variant, ch, 0); - } - int decodedData = bits; - - // then second base64 char; can't get padding yet, nor ws - - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++]; - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - throw reportInvalidChar(b64variant, ch, 1); - } - decodedData = (decodedData << 6) | bits; - - // third base64 char; can be padding, but not ws - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++]; - bits = b64variant.decodeBase64Char(ch); - - // First branch: can get padding (-> 1 byte) - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - throw reportInvalidChar(b64variant, ch, 2); - } - // Ok, must get padding - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++]; - if (!b64variant.usesPaddingChar(ch)) { - throw reportInvalidChar(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'"); - } - // Got 12 bits, only need 8, need to shift - decodedData >>= 4; - builder.append(decodedData); - continue; - } - // Nope, 2 or 3 bytes - decodedData = (decodedData << 6) | bits; - // fourth and last base64 char; can be padding, but not ws - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++]; - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - throw reportInvalidChar(b64variant, ch, 3); - } - /* With padding we only get 2 bytes; but we have - * to shift it a bit so it is identical to triplet - * case with partial output. - * 3 chars gives 3x6 == 18 bits, of which 2 are - * dummies, need to discard: - */ - decodedData >>= 2; - builder.appendTwoBytes(decodedData); - } else { - // otherwise, our triple is now complete - decodedData = (decodedData << 6) | bits; - builder.appendThreeBytes(decodedData); - } - } - } - - protected IllegalArgumentException reportInvalidChar(Base64Variant b64variant, char ch, int bindex) - throws IllegalArgumentException - { - return reportInvalidChar(b64variant, ch, bindex, null); - } - - /** - * @param b64variant Undocumented. - * @param ch Undocumented. - * @param bindex Relative index within base64 character unit; between 0 - * and 3 (as unit has exactly 4 characters) - * @param msg Undocumented. - * @return Undocumented. - */ - protected IllegalArgumentException reportInvalidChar(Base64Variant b64variant, char ch, int bindex, String msg) - throws IllegalArgumentException - { - String base; - if (ch <= INT_SPACE) { - base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units"; - } else if (b64variant.usesPaddingChar(ch)) { - base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character"; - } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) { - // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level) - base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } else { - base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } - if (msg != null) { - base = base + ": " + msg; - } - return new IllegalArgumentException(base); - } -} diff --git a/src/org/codehaus/jackson/impl/ReaderBasedParserBase.java b/src/org/codehaus/jackson/impl/ReaderBasedParserBase.java deleted file mode 100644 index a0edd80df2..0000000000 --- a/src/org/codehaus/jackson/impl/ReaderBasedParserBase.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.IOContext; - -/** - * This is a simple low-level input reader base class, used by - * JSON parser. - * The reason for sub-classing (over composition) - * is due to need for direct access to character buffers - * and positions. - * - * @author Tatu Saloranta - */ -public abstract class ReaderBasedParserBase - extends JsonNumericParserBase -{ - /* - //////////////////////////////////////////////////// - // Configuration - //////////////////////////////////////////////////// - */ - - /** - * Reader that can be used for reading more content, if one - * buffer from input source, but in some cases pre-loaded buffer - * is handed to the parser. - */ - protected Reader _reader; - - /* - //////////////////////////////////////////////////// - // Current input data - //////////////////////////////////////////////////// - */ - - /** - * Current buffer from which data is read; generally data is read into - * buffer from input source. - */ - protected char[] _inputBuffer; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - protected ReaderBasedParserBase(IOContext ctxt, int features, Reader r) - { - super(ctxt, features); - _reader = r; - _inputBuffer = ctxt.allocTokenBuffer(); - } - - /* - //////////////////////////////////////////////////// - // Low-level reading, other - //////////////////////////////////////////////////// - */ - - @Override - protected final boolean loadMore() - throws IOException - { - _currInputProcessed += _inputEnd; - _currInputRowStart -= _inputEnd; - - if (_reader != null) { - int count = _reader.read(_inputBuffer, 0, _inputBuffer.length); - if (count > 0) { - _inputPtr = 0; - _inputEnd = count; - return true; - } - // End of input - _closeInput(); - // Should never return 0, so let's fail - if (count == 0) { - throw new IOException("Reader returned 0 characters when trying to read "+_inputEnd); - } - } - return false; - } - - protected char getNextChar(String eofMsg) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(eofMsg); - } - } - return _inputBuffer[_inputPtr++]; - } - - @Override - protected void _closeInput() throws IOException - { - /* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close() - * on the underlying Reader, unless we "own" it, or auto-closing - * feature is enabled. - * One downside is that when using our optimized - * Reader (granted, we only do that for UTF-32...) this - * means that buffer recycling won't work correctly. - */ - if (_reader != null) { - if (_ioContext.isResourceManaged() || isEnabled(Feature.AUTO_CLOSE_SOURCE)) { - _reader.close(); - } - _reader = null; - } - } - - /** - * Method called to release internal buffers owned by the base - * reader. This may be called along with {@link #_closeInput} (for - * example, when explicitly closing this reader instance), or - * separately (if need be). - */ - @Override - protected void _releaseBuffers() - throws IOException - { - super._releaseBuffers(); - char[] buf = _inputBuffer; - if (buf != null) { - _inputBuffer = null; - _ioContext.releaseTokenBuffer(buf); - } - } -} diff --git a/src/org/codehaus/jackson/impl/StreamBasedParserBase.java b/src/org/codehaus/jackson/impl/StreamBasedParserBase.java deleted file mode 100644 index a7ac7e539d..0000000000 --- a/src/org/codehaus/jackson/impl/StreamBasedParserBase.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.io.IOContext; - -/** - * This is a simple low-level input reader base class, used by - * JSON parser. It is used when underlying input source is - * a byte stream such as {@link InputStream}. - * The reason for sub-classing (over composition) - * is due to need for direct access to low-level byte buffers - * and positions. - * - * @author Tatu Saloranta - */ -public abstract class StreamBasedParserBase - extends JsonNumericParserBase -{ - /* - //////////////////////////////////////////////////// - // Configuration - //////////////////////////////////////////////////// - */ - - /** - * Input stream that can be used for reading more content, if one - * in use. May be null, if input comes just as a full buffer, - * or if the stream has been closed. - */ - protected InputStream _inputStream; - - /* - //////////////////////////////////////////////////// - // Current input data - //////////////////////////////////////////////////// - */ - - /** - * Current buffer from which data is read; generally data is read into - * buffer from input source, but in some cases pre-loaded buffer - * is handed to the parser. - */ - protected byte[] _inputBuffer; - - /** - * Flag that indicates whether the input buffer is recycable (and - * needs to be returned to recycler once we are done) or not. - */ - protected boolean _bufferRecyclable; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - protected StreamBasedParserBase(IOContext ctxt, int features, - InputStream in, - byte[] inputBuffer, int start, int end, - boolean bufferRecyclable) - { - super(ctxt, features); - _inputStream = in; - _inputBuffer = inputBuffer; - _inputPtr = start; - _inputEnd = end; - _bufferRecyclable = bufferRecyclable; - } - - /* - //////////////////////////////////////////////////// - // Low-level reading, other - //////////////////////////////////////////////////// - */ - - @Override - protected final boolean loadMore() - throws IOException - { - _currInputProcessed += _inputEnd; - _currInputRowStart -= _inputEnd; - - if (_inputStream != null) { - int count = _inputStream.read(_inputBuffer, 0, _inputBuffer.length); - if (count > 0) { - _inputPtr = 0; - _inputEnd = count; - return true; - } - // End of input - _closeInput(); - // Should never return 0, so let's fail - if (count == 0) { - throw new IOException("Reader returned 0 characters when trying to read "+_inputEnd); - } - } - return false; - } - - @Override - protected void _closeInput() throws IOException - { - /* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close() - * on the underlying Reader, unless we "own" it, or auto-closing - * feature is enabled. - */ - if (_inputStream != null) { - if (_ioContext.isResourceManaged() || isEnabled(Feature.AUTO_CLOSE_SOURCE)) { - _inputStream.close(); - } - _inputStream = null; - } - } - - /** - * Method called to release internal buffers owned by the base - * reader. This may be called along with {@link #_closeInput} (for - * example, when explicitly closing this reader instance), or - * separately (if need be). - */ - @Override - protected void _releaseBuffers() throws IOException - { - super._releaseBuffers(); - if (_bufferRecyclable) { - byte[] buf = _inputBuffer; - if (buf != null) { - _inputBuffer = null; - _ioContext.releaseReadIOBuffer(buf); - } - } - } -} diff --git a/src/org/codehaus/jackson/impl/Utf8NumericParser.java b/src/org/codehaus/jackson/impl/Utf8NumericParser.java deleted file mode 100644 index bd710d2264..0000000000 --- a/src/org/codehaus/jackson/impl/Utf8NumericParser.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.JsonParseException; -import org.codehaus.jackson.JsonToken; - -/** - * Intermediate class that implements handling of numeric parsing, - * when using UTF-8 encoded byte-based input source. - * Separate from the actual parser class just to isolate numeric - * parsing: would be nice to use aggregation, but unfortunately - * many parts are hard to implement without direct access to - * underlying buffers. - */ -public abstract class Utf8NumericParser - extends StreamBasedParserBase -{ - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - public Utf8NumericParser(IOContext pc, int features, - InputStream in, - byte[] inputBuffer, int start, int end, - boolean bufferRecyclable) - { - super(pc, features, in, inputBuffer, start, end, bufferRecyclable); - } - - /* - //////////////////////////////////////////////////// - // Textual parsing of number values - //////////////////////////////////////////////////// - */ - - /** - * Initial parsing method for number values. It needs to be able - * to parse enough input to be able to determine whether the - * value is to be considered a simple integer value, or a more - * generic decimal value: latter of which needs to be expressed - * as a floating point number. The basic rule is that if the number - * has no fractional or exponential part, it is an integer; otherwise - * a floating point number. - *

- * Because much of input has to be processed in any case, no partial - * parsing is done: all input text will be stored for further - * processing. However, actual numeric value conversion will be - * deferred, since it is usually the most complicated and costliest - * part of processing. - */ - @Override - protected final JsonToken parseNumberText(int c) - throws IOException, JsonParseException - { - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - int outPtr = 0; - boolean negative = (c == INT_MINUS); - - // Need to prepend sign? - if (negative) { - outBuf[outPtr++] = '-'; - // Must have something after sign too - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - } - - int intLen = 0; - boolean eof = false; - - // Ok, first the obligatory integer part: - int_loop: - while (true) { - if (c < INT_0 || c > INT_9) { - break int_loop; - } - ++intLen; - // Quickie check: no leading zeroes allowed - if (intLen == 2) { - if (outBuf[outPtr-1] == '0') { - reportInvalidNumber("Leading zeroes not allowed"); - } - } - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = (char) c; - if (_inputPtr >= _inputEnd && !loadMore()) { - // EOF is legal for main level int values - c = CHAR_NULL; - eof = true; - break int_loop; - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - } - // Also, integer part is not optional - if (intLen == 0) { - reportInvalidNumber("Missing integer part (next char "+_getCharDesc(c)+")"); - } - - int fractLen = 0; - // And then see if we get other parts - if (c == '.') { // yes, fraction - outBuf[outPtr++] = (char) c; - - fract_loop: - while (true) { - if (_inputPtr >= _inputEnd && !loadMore()) { - eof = true; - break fract_loop; - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - if (c < INT_0 || c > INT_9) { - break fract_loop; - } - ++fractLen; - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = (char) c; - } - // must be followed by sequence of ints, one minimum - if (fractLen == 0) { - reportUnexpectedNumberChar(c, "Decimal point not followed by a digit"); - } - } - - int expLen = 0; - if (c == 'e' || c == 'E') { // exponent? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = (char) c; - // Not optional, can require that we get one more char - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - // Sign indicator? - if (c == '-' || c == '+') { - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = (char) c; - // Likewise, non optional: - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - } - - exp_loop: - while (c <= INT_9 && c >= INT_0) { - ++expLen; - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - outBuf[outPtr++] = (char) c; - if (_inputPtr >= _inputEnd && !loadMore()) { - eof = true; - break exp_loop; - } - c = (int) _inputBuffer[_inputPtr++] & 0xFF; - } - // must be followed by sequence of ints, one minimum - if (expLen == 0) { - reportUnexpectedNumberChar(c, "Exponent indicator not followed by a digit"); - } - } - - // Ok; unless we hit end-of-input, need to push last char read back - if (!eof) { - --_inputPtr; - } - _textBuffer.setCurrentLength(outPtr); - - // And there we have it! - return reset(negative, intLen, fractLen, expLen); - } -} diff --git a/src/org/codehaus/jackson/impl/Utf8StreamParser.java b/src/org/codehaus/jackson/impl/Utf8StreamParser.java deleted file mode 100644 index 4103317552..0000000000 --- a/src/org/codehaus/jackson/impl/Utf8StreamParser.java +++ /dev/null @@ -1,1849 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.IOContext; -import org.codehaus.jackson.sym.*; -import org.codehaus.jackson.util.*; - -/** - * This is a concrete implementation of {@link JsonParser}, which is - * based on a {@link java.io.InputStream} as the input source. - */ -public final class Utf8StreamParser - extends Utf8NumericParser -{ - final static byte BYTE_LF = (byte) '\n'; - - /* - /*************************************************** - /* Configuration, state - /*************************************************** - */ - - /** - * Codec used for data binding when (if) requested. - */ - protected ObjectCodec _objectCodec; - - /** - * Symbol table that contains field names encountered so far - */ - final protected BytesToNameCanonicalizer _symbols; - - /** - * Temporary buffer used for name parsing. - */ - protected int[] _quadBuffer = new int[32]; - - /* - /*************************************************** - /* Life-cycle - /*************************************************** - */ - - public Utf8StreamParser(IOContext ctxt, int features, InputStream in, - ObjectCodec codec, - BytesToNameCanonicalizer sym, - byte[] inputBuffer, int start, int end, - boolean bufferRecyclable) - { - super(ctxt, features, in, inputBuffer, start, end, bufferRecyclable); - _objectCodec = codec; - _symbols = sym; - // 12-Mar-2010, tatus: Sanity check, related to [JACKSON-259]: - if (!JsonParser.Feature.CANONICALIZE_FIELD_NAMES.enabledIn(features)) { - // should never construct non-canonical utf8/byte parser (instead, use Reader) - _throwInternal(); - } - } - - public ObjectCodec getCodec() { - return _objectCodec; - } - - public void setCodec(ObjectCodec c) { - _objectCodec = c; - } - - /* - /*************************************************** - /* Public API, traversal - /*************************************************** - */ - - /** - * @return Next token from the stream, if any found, or null - * to indicate end-of-input - */ - @Override - public JsonToken nextToken() - throws IOException, JsonParseException - { - /* First: field names are special -- we will always tokenize - * (part of) value along with field name to simplify - * state handling. If so, can and need to use secondary token: - */ - if (_currToken == JsonToken.FIELD_NAME) { - return _nextAfterName(); - } - if (_tokenIncomplete) { - _skipString(); // only strings can be partial - } - - int i = _skipWSOrEnd(); - if (i < 0) { // end-of-input - /* 19-Feb-2009, tatu: Should actually close/release things - * like input source, symbol table and recyclable buffers now. - */ - close(); - return (_currToken = null); - } - - /* First, need to ensure we know the starting location of token - * after skipping leading white space - */ - _tokenInputTotal = _currInputProcessed + _inputPtr - 1; - _tokenInputRow = _currInputRow; - _tokenInputCol = _inputPtr - _currInputRowStart - 1; - - // finally: clear any data retained so far - _binaryValue = null; - - // Closing scope? - if (i == INT_RBRACKET) { - if (!_parsingContext.inArray()) { - _reportMismatchedEndMarker(i, '}'); - } - _parsingContext = _parsingContext.getParent(); - return (_currToken = JsonToken.END_ARRAY); - } - if (i == INT_RCURLY) { - if (!_parsingContext.inObject()) { - _reportMismatchedEndMarker(i, ']'); - } - _parsingContext = _parsingContext.getParent(); - return (_currToken = JsonToken.END_OBJECT); - } - - // Nope: do we then expect a comma? - if (_parsingContext.expectComma()) { - if (i != INT_COMMA) { - _reportUnexpectedChar(i, "was expecting comma to separate "+_parsingContext.getTypeDesc()+" entries"); - } - i = _skipWS(); - } - - /* And should we now have a name? Always true for - * Object contexts, since the intermediate 'expect-value' - * state is never retained. - */ - boolean inObject = _parsingContext.inObject(); - if (inObject) { - // First, field name itself: - Name n = _parseFieldName(i); - _parsingContext.setCurrentName(n.getName()); - _currToken = JsonToken.FIELD_NAME; - i = _skipWS(); - if (i != INT_COLON) { - _reportUnexpectedChar(i, "was expecting a colon to separate field name and value"); - } - i = _skipWS(); - } - - // Ok: we must have a value... what is it? - - JsonToken t; - - switch (i) { - case INT_QUOTE: - _tokenIncomplete = true; - t = JsonToken.VALUE_STRING; - break; - case INT_LBRACKET: - if (!inObject) { - _parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol); - } - t = JsonToken.START_ARRAY; - break; - case INT_LCURLY: - if (!inObject) { - _parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol); - } - t = JsonToken.START_OBJECT; - break; - case INT_RBRACKET: - case INT_RCURLY: - // Error: neither is valid at this point; valid closers have - // been handled earlier - _reportUnexpectedChar(i, "expected a value"); - case INT_t: - _matchToken(JsonToken.VALUE_TRUE); - t = JsonToken.VALUE_TRUE; - break; - case INT_f: - _matchToken(JsonToken.VALUE_FALSE); - t = JsonToken.VALUE_FALSE; - break; - case INT_n: - _matchToken(JsonToken.VALUE_NULL); - t = JsonToken.VALUE_NULL; - break; - - case INT_MINUS: - /* Should we have separate handling for plus? Although - * it is not allowed per se, it may be erroneously used, - * and could be indicate by a more specific error message. - */ - case INT_0: - case INT_1: - case INT_2: - case INT_3: - case INT_4: - case INT_5: - case INT_6: - case INT_7: - case INT_8: - case INT_9: - t = parseNumberText(i); - break; - default: - t = _handleUnexpectedValue(i); - } - - if (inObject) { - _nextToken = t; - return _currToken; - } - _currToken = t; - return t; - } - - private final JsonToken _nextAfterName() - { - _nameCopied = false; // need to invalidate if it was copied - JsonToken t = _nextToken; - _nextToken = null; - // Also: may need to start new context? - if (t == JsonToken.START_ARRAY) { - _parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol); - } else if (t == JsonToken.START_OBJECT) { - _parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol); - } - return (_currToken = t); - } - - @Override - public void close() throws IOException - { - super.close(); - // Merge found symbols, if any: - _symbols.release(); - } - - /* - /*************************************************** - /* Internal methods, secondary parsing - /*************************************************** - */ - - protected final Name _parseFieldName(int i) - throws IOException, JsonParseException - { - if (i != INT_QUOTE) { - return _handleUnusualFieldName(i); - } - // First: can we optimize out bounds checks? - if ((_inputEnd - _inputPtr) < 9) { // Need 8 chars, plus one trailing (quote) - return slowParseFieldName(); - } - - // If so, can also unroll loops nicely - /* 25-Nov-2008, tatu: This may seem weird, but here we do - * NOT want to worry about UTF-8 decoding. Rather, we'll - * assume that part is ok (if not it will get caught - * later on), and just handle quotes and backslashes here. - */ - final int[] codes = CharTypes.getInputCodeLatin1(); - - int q = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[q] != 0) { - if (q == INT_QUOTE) { // special case, "" - return BytesToNameCanonicalizer.getEmptyName(); - } - return parseFieldName(0, q, 0); // quoting or invalid char - } - - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // one byte/char case or broken - return findName(q, 1); - } - return parseFieldName(q, i, 1); - } - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // two byte name or broken - return findName(q, 2); - } - return parseFieldName(q, i, 2); - } - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // three byte name or broken - return findName(q, 3); - } - return parseFieldName(q, i, 3); - } - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // four byte name or broken - return findName(q, 4); - } - return parseFieldName(q, i, 4); - } - return parseMediumFieldName(q, i); - } - - protected Name parseMediumFieldName(int q1, int q2) - throws IOException, JsonParseException - { - // As mentioned earlier, we do ignore UTF-8 aspects at this point - final int[] codes = CharTypes.getInputCodeLatin1(); - - // Ok, got 5 name bytes so far - int i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // 5 bytes - return findName(q1, q2, 1); - } - return parseFieldName(q1, q2, i, 1); // quoting or invalid char - } - q2 = (q2 << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // 6 bytes - return findName(q1, q2, 2); - } - return parseFieldName(q1, q2, i, 2); - } - q2 = (q2 << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // 7 bytes - return findName(q1, q2, 3); - } - return parseFieldName(q1, q2, i, 3); - } - q2 = (q2 << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { // 8 bytes - return findName(q1, q2, 4); - } - return parseFieldName(q1, q2, i, 4); - } - _quadBuffer[0] = q1; - _quadBuffer[1] = q2; - return parseLongFieldName(i); - } - - protected Name parseLongFieldName(int q) - throws IOException, JsonParseException - { - // As explained above, will ignore utf-8 encoding at this point - final int[] codes = CharTypes.getInputCodeLatin1(); - int qlen = 2; - - while (true) { - /* Let's offline if we hit buffer boundary (otherwise would - * need to [try to] align input, which is bit complicated - * and may not always be possible) - */ - if ((_inputEnd - _inputPtr) < 4) { - return parseEscapedFieldName(_quadBuffer, qlen, 0, q, 0); - } - // Otherwise can skip boundary checks for 4 bytes in loop - - int i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { - return findName(_quadBuffer, qlen, q, 1); - } - return parseEscapedFieldName(_quadBuffer, qlen, q, i, 1); - } - - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { - return findName(_quadBuffer, qlen, q, 2); - } - return parseEscapedFieldName(_quadBuffer, qlen, q, i, 2); - } - - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { - return findName(_quadBuffer, qlen, q, 3); - } - return parseEscapedFieldName(_quadBuffer, qlen, q, i, 3); - } - - q = (q << 8) | i; - i = _inputBuffer[_inputPtr++] & 0xFF; - if (codes[i] != 0) { - if (i == INT_QUOTE) { - return findName(_quadBuffer, qlen, q, 4); - } - return parseEscapedFieldName(_quadBuffer, qlen, q, i, 4); - } - - // Nope, no end in sight. Need to grow quad array etc - if (qlen >= _quadBuffer.length) { - _quadBuffer = growArrayBy(_quadBuffer, qlen); - } - _quadBuffer[qlen++] = q; - q = i; - } - } - - /** - * Method called when not even first 8 bytes are guaranteed to come consequtively.Happens rarely, so this is - * offlined; plus we'll also do full checks for escaping etc. - * - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected Name slowParseFieldName() - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing '\"' for name"); - } - } - int i = _inputBuffer[_inputPtr++] & 0xFF; - if (i == INT_QUOTE) { // special case, "" - return BytesToNameCanonicalizer.getEmptyName(); - } - return parseEscapedFieldName(_quadBuffer, 0, 0, i, 0); - } - - private final Name parseFieldName(int q1, int ch, int lastQuadBytes) - throws IOException, JsonParseException - { - return parseEscapedFieldName(_quadBuffer, 0, q1, ch, lastQuadBytes); - } - - private final Name parseFieldName(int q1, int q2, int ch, int lastQuadBytes) - throws IOException, JsonParseException - { - _quadBuffer[0] = q1; - return parseEscapedFieldName(_quadBuffer, 1, q2, ch, lastQuadBytes); - } - - /** - * Slower parsing method which is generally branched to when an escape sequence is detected (or alternatively for - * long names, or ones crossing input buffer boundary).In any case, needs to be able to handle more exceptional - * cases, gets slower, and hance is offlined to a separate method. - * - * @param quads Undocumented. - * @param qlen Undocumented. - * @param currQuad Undocumented. - * @param ch Undocumented. - * @param currQuadBytes Undocumented. - * @return Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected Name parseEscapedFieldName(int[] quads, int qlen, int currQuad, int ch, - int currQuadBytes) - throws IOException, JsonParseException - { - /* 25-Nov-2008, tatu: This may seem weird, but here we do - * NOT want to worry about UTF-8 decoding. Rather, we'll - * assume that part is ok (if not it will get caught - * later on), and just handle quotes and backslashes here. - */ - final int[] codes = CharTypes.getInputCodeLatin1(); - - while (true) { - if (codes[ch] != 0) { - if (ch == INT_QUOTE) { // we are done - break; - } - // Unquoted white space? - if (ch != INT_BACKSLASH) { - // As per [JACKSON-208], call can now return: - _throwUnquotedSpace(ch, "name"); - } else { - // Nope, escape sequence - ch = _decodeEscaped(); - } - /* Oh crap. May need to UTF-8 (re-)encode it, if it's - * beyond 7-bit ascii. Gets pretty messy. - * If this happens often, may want to use different name - * canonicalization to avoid these hits. - */ - if (ch > 127) { - // Ok, we'll need room for first byte right away - if (currQuadBytes >= 4) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = 0; - currQuadBytes = 0; - } - if (ch < 0x800) { // 2-byte - currQuad = (currQuad << 8) | (0xc0 | (ch >> 6)); - ++currQuadBytes; - // Second byte gets output below: - } else { // 3 bytes; no need to worry about surrogates here - currQuad = (currQuad << 8) | (0xe0 | (ch >> 12)); - ++currQuadBytes; - // need room for middle byte? - if (currQuadBytes >= 4) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = 0; - currQuadBytes = 0; - } - currQuad = (currQuad << 8) | (0x80 | ((ch >> 6) & 0x3f)); - ++currQuadBytes; - } - // And same last byte in both cases, gets output below: - ch = 0x80 | (ch & 0x3f); - } - } - // Ok, we have one more byte to add at any rate: - if (currQuadBytes < 4) { - ++currQuadBytes; - currQuad = (currQuad << 8) | ch; - } else { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = ch; - currQuadBytes = 1; - } - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in field name"); - } - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - } - - if (currQuadBytes > 0) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - } - Name name = _symbols.findName(quads, qlen); - if (name == null) { - name = addName(quads, qlen, currQuadBytes); - } - return name; - } - - /** - * Method called when we see non-white space character other - * than double quote, when expecting a field name.In standard mode will just throw an expection; but - in non-standard modes may be able to parse name. - * @param ch Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected final Name _handleUnusualFieldName(int ch) - throws IOException, JsonParseException - { - // [JACKSON-173]: allow single quotes - if (ch == INT_APOSTROPHE && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { - return _parseApostropheFieldName(); - } - // [JACKSON-69]: allow unquoted names if feature enabled: - if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) { - _reportUnexpectedChar(ch, "was expecting double-quote to start field name"); - } - /* Also: note that although we use a different table here, - * it does NOT handle UTF-8 decoding. It'll just pass those - * high-bit codes as acceptable for later decoding. - */ - final int[] codes = CharTypes.getInputCodeUtf8JsNames(); - // Also: must start with a valid character... - if (codes[ch] != 0) { - _reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name"); - } - - /* Ok, now; instead of ultra-optimizing parsing here (as with - * regular JSON names), let's just use the generic "slow" - * variant. Can measure its impact later on if need be - */ - int[] quads = _quadBuffer; - int qlen = 0; - int currQuad = 0; - int currQuadBytes = 0; - - while (true) { - // Ok, we have one more byte to add at any rate: - if (currQuadBytes < 4) { - ++currQuadBytes; - currQuad = (currQuad << 8) | ch; - } else { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = ch; - currQuadBytes = 1; - } - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in field name"); - } - } - ch = _inputBuffer[_inputPtr] & 0xFF; - if (codes[ch] != 0) { - break; - } - ++_inputPtr; - } - - if (currQuadBytes > 0) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - } - Name name = _symbols.findName(quads, qlen); - if (name == null) { - name = addName(quads, qlen, currQuadBytes); - } - return name; - } - - /* Parsing to support [JACKSON-173]. Plenty of duplicated code; - * main reason being to try to avoid slowing down fast path - * for valid JSON -- more alternatives, more code, generally - * bit slower execution. - */ - protected final Name _parseApostropheFieldName() - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(": was expecting closing '\'' for name"); - } - } - int ch = _inputBuffer[_inputPtr++] & 0xFF; - if (ch == INT_APOSTROPHE) { // special case, '' - return BytesToNameCanonicalizer.getEmptyName(); - } - int[] quads = _quadBuffer; - int qlen = 0; - int currQuad = 0; - int currQuadBytes = 0; - - // Copied from parseEscapedFieldName, with minor mods: - - final int[] codes = CharTypes.getInputCodeLatin1(); - - while (true) { - if (ch == INT_APOSTROPHE) { - break; - } - // additional check to skip handling of double-quotes - if (ch != INT_QUOTE && codes[ch] != 0) { - if (ch != INT_BACKSLASH) { - // Unquoted white space? - // As per [JACKSON-208], call can now return: - _throwUnquotedSpace(ch, "name"); - } else { - // Nope, escape sequence - ch = _decodeEscaped(); - } - /* Oh crap. May need to UTF-8 (re-)encode it, if it's - * beyond 7-bit ascii. Gets pretty messy. - * If this happens often, may want to use different name - * canonicalization to avoid these hits. - */ - if (ch > 127) { - // Ok, we'll need room for first byte right away - if (currQuadBytes >= 4) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = 0; - currQuadBytes = 0; - } - if (ch < 0x800) { // 2-byte - currQuad = (currQuad << 8) | (0xc0 | (ch >> 6)); - ++currQuadBytes; - // Second byte gets output below: - } else { // 3 bytes; no need to worry about surrogates here - currQuad = (currQuad << 8) | (0xe0 | (ch >> 12)); - ++currQuadBytes; - // need room for middle byte? - if (currQuadBytes >= 4) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = 0; - currQuadBytes = 0; - } - currQuad = (currQuad << 8) | (0x80 | ((ch >> 6) & 0x3f)); - ++currQuadBytes; - } - // And same last byte in both cases, gets output below: - ch = 0x80 | (ch & 0x3f); - } - } - // Ok, we have one more byte to add at any rate: - if (currQuadBytes < 4) { - ++currQuadBytes; - currQuad = (currQuad << 8) | ch; - } else { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - currQuad = ch; - currQuadBytes = 1; - } - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in field name"); - } - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - } - - if (currQuadBytes > 0) { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = currQuad; - } - Name name = _symbols.findName(quads, qlen); - if (name == null) { - name = addName(quads, qlen, currQuadBytes); - } - return name; - } - - /* - /*************************************************** - /* Internal methods, symbol (name) handling - /*************************************************** - */ - - private final Name findName(int q1, int lastQuadBytes) - throws JsonParseException - { - // Usually we'll find it from the canonical symbol table already - Name name = _symbols.findName(q1); - if (name != null) { - return name; - } - // If not, more work. We'll need add stuff to buffer - _quadBuffer[0] = q1; - return addName(_quadBuffer, 1, lastQuadBytes); - } - - private final Name findName(int q1, int q2, int lastQuadBytes) - throws JsonParseException - { - // Usually we'll find it from the canonical symbol table already - Name name = _symbols.findName(q1, q2); - if (name != null) { - return name; - } - // If not, more work. We'll need add stuff to buffer - _quadBuffer[0] = q1; - _quadBuffer[1] = q2; - return addName(_quadBuffer, 2, lastQuadBytes); - } - - private final Name findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes) - throws JsonParseException - { - if (qlen >= quads.length) { - _quadBuffer = quads = growArrayBy(quads, quads.length); - } - quads[qlen++] = lastQuad; - Name name = _symbols.findName(quads, qlen); - if (name == null) { - return addName(quads, qlen, lastQuadBytes); - } - return name; - } - - /** - * This is the main workhorse method used when we take a symbol - * table miss. It needs to demultiplex individual bytes, decode - * multi-byte chars (if any), and then construct Name instance - * and add it to the symbol table. - */ - private final Name addName(int[] quads, int qlen, int lastQuadBytes) - throws JsonParseException - { - /* Ok: must decode UTF-8 chars. No other validation is - * needed, since unescaping has been done earlier as necessary - * (as well as error reporting for unescaped control chars) - */ - // 4 bytes per quad, except last one maybe less - int byteLen = (qlen << 2) - 4 + lastQuadBytes; - - /* And last one is not correctly aligned (leading zero bytes instead - * need to shift a bit, instead of trailing). Only need to shift it - * for UTF-8 decoding; need revert for storage (since key will not - * be aligned, to optimize lookup speed) - */ - int lastQuad; - - if (lastQuadBytes < 4) { - lastQuad = quads[qlen-1]; - // 8/16/24 bit left shift - quads[qlen-1] = (lastQuad << ((4 - lastQuadBytes) << 3)); - } else { - lastQuad = 0; - } - - // Need some working space, TextBuffer works well: - char[] cbuf = _textBuffer.emptyAndGetCurrentSegment(); - int cix = 0; - - for (int ix = 0; ix < byteLen; ) { - int ch = quads[ix >> 2]; // current quad, need to shift+mask - int byteIx = (ix & 3); - ch = (ch >> ((3 - byteIx) << 3)) & 0xFF; - ++ix; - - if (ch > 127) { // multi-byte - int needed; - if ((ch & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF) - ch &= 0x1F; - needed = 1; - } else if ((ch & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF) - ch &= 0x0F; - needed = 2; - } else if ((ch & 0xF8) == 0xF0) { // 4 bytes; double-char with surrogates and all... - ch &= 0x07; - needed = 3; - } else { // 5- and 6-byte chars not valid xml chars - _reportInvalidInitial(ch); - needed = ch = 1; // never really gets this far - } - if ((ix + needed) > byteLen) { - _reportInvalidEOF(" in field name"); - } - - // Ok, always need at least one more: - int ch2 = quads[ix >> 2]; // current quad, need to shift+mask - byteIx = (ix & 3); - ch2 = (ch2 >> ((3 - byteIx) << 3)); - ++ix; - - if ((ch2 & 0xC0) != 0x080) { - _reportInvalidOther(ch2); - } - ch = (ch << 6) | (ch2 & 0x3F); - if (needed > 1) { - ch2 = quads[ix >> 2]; - byteIx = (ix & 3); - ch2 = (ch2 >> ((3 - byteIx) << 3)); - ++ix; - - if ((ch2 & 0xC0) != 0x080) { - _reportInvalidOther(ch2); - } - ch = (ch << 6) | (ch2 & 0x3F); - if (needed > 2) { // 4 bytes? (need surrogates on output) - ch2 = quads[ix >> 2]; - byteIx = (ix & 3); - ch2 = (ch2 >> ((3 - byteIx) << 3)); - ++ix; - if ((ch2 & 0xC0) != 0x080) { - _reportInvalidOther(ch2 & 0xFF); - } - ch = (ch << 6) | (ch2 & 0x3F); - } - } - if (needed > 2) { // surrogate pair? once again, let's output one here, one later on - ch -= 0x10000; // to normalize it starting with 0x0 - if (cix >= cbuf.length) { - cbuf = _textBuffer.expandCurrentSegment(); - } - cbuf[cix++] = (char) (0xD800 + (ch >> 10)); - ch = 0xDC00 | (ch & 0x03FF); - } - } - if (cix >= cbuf.length) { - cbuf = _textBuffer.expandCurrentSegment(); - } - cbuf[cix++] = (char) ch; - } - - /* Ok. Now we have the character array, and can construct the - * String (as well as check proper composition of semicolons - * for ns-aware mode...) - */ - String baseName = new String(cbuf, 0, cix); - // And finally, un-align if necessary - if (lastQuadBytes < 4) { - quads[qlen-1] = lastQuad; - } - return _symbols.addName(baseName, quads, qlen); - } - - /* - /*************************************************** - /* Internal methods, String value parsing - /*************************************************** - */ - - @Override - protected void _finishString() - throws IOException, JsonParseException - { - int outPtr = 0; - int c; - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - - // Here we do want to do full decoding, hence: - final int[] codes = CharTypes.getInputCodeUtf8(); - final byte[] inputBuffer = _inputBuffer; - - main_loop: - while (true) { - // Then the tight ascii non-funny-char loop: - ascii_loop: - while (true) { - int ptr = _inputPtr; - if (ptr >= _inputEnd) { - loadMoreGuaranteed(); - ptr = _inputPtr; - } - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - int max = _inputEnd; - { - int max2 = ptr + (outBuf.length - outPtr); - if (max2 < max) { - max = max2; - } - } - while (ptr < max) { - c = (int) inputBuffer[ptr++] & 0xFF; - if (codes[c] != 0) { - _inputPtr = ptr; - break ascii_loop; - } - outBuf[outPtr++] = (char) c; - } - _inputPtr = ptr; - } - // Ok: end marker, escape or multi-byte? - if (c == INT_QUOTE) { - break main_loop; - } - - switch (codes[c]) { - case 1: // backslash - c = _decodeEscaped(); - break; - case 2: // 2-byte UTF - c = _decodeUtf8_2(c); - break; - case 3: // 3-byte UTF - if ((_inputEnd - _inputPtr) >= 2) { - c = _decodeUtf8_3fast(c); - } else { - c = _decodeUtf8_3(c); - } - break; - case 4: // 4-byte UTF - c = _decodeUtf8_4(c); - // Let's add first part right away: - outBuf[outPtr++] = (char) (0xD800 | (c >> 10)); - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - c = 0xDC00 | (c & 0x3FF); - // And let the other char output down below - break; - default: - if (c < INT_SPACE) { - // As per [JACKSON-208], call can now return: - _throwUnquotedSpace(c, "string value"); - } else { - // Is this good enough error message? - _reportInvalidChar(c); - } - } - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - // Ok, let's add char to output: - outBuf[outPtr++] = (char) c; - } - _textBuffer.setCurrentLength(outPtr); - } - - /** - * Method called to skim through rest of unparsed String value, if it is not needed.This can be done bit faster if - * contents need not be stored for future access. - * - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _skipString() - throws IOException, JsonParseException - { - _tokenIncomplete = false; - - // Need to be fully UTF-8 aware here: - final int[] codes = CharTypes.getInputCodeUtf8(); - final byte[] inputBuffer = _inputBuffer; - - main_loop: - while (true) { - int c; - - ascii_loop: - while (true) { - int ptr = _inputPtr; - int max = _inputEnd; - if (ptr >= max) { - loadMoreGuaranteed(); - ptr = _inputPtr; - max = _inputEnd; - } - while (ptr < max) { - c = (int) inputBuffer[ptr++] & 0xFF; - if (codes[c] != 0) { - _inputPtr = ptr; - break ascii_loop; - } - } - _inputPtr = ptr; - } - // Ok: end marker, escape or multi-byte? - if (c == INT_QUOTE) { - break main_loop; - } - - switch (codes[c]) { - case 1: // backslash - _decodeEscaped(); - break; - case 2: // 2-byte UTF - _skipUtf8_2(c); - break; - case 3: // 3-byte UTF - _skipUtf8_3(c); - break; - case 4: // 4-byte UTF - _skipUtf8_4(c); - break; - default: - if (c < INT_SPACE) { - // As per [JACKSON-208], call can now return: - _throwUnquotedSpace(c, "string value"); - } else { - // Is this good enough error message? - _reportInvalidChar(c); - } - } - } - } - - /** - * Method for handling cases where first non-space character - * of an expected value token is not legal for standard JSON content. - * - * @param c Undocumented. - * @return Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - * @since 1.3 - */ - protected final JsonToken _handleUnexpectedValue(int c) - throws IOException, JsonParseException - { - // Most likely an error, unless we are to allow single-quote-strings - if (c != INT_APOSTROPHE || !isEnabled(Feature.ALLOW_SINGLE_QUOTES)) { - _reportUnexpectedChar(c, "expected a valid value (number, String, array, object, 'true', 'false' or 'null')"); - } - - // Otherwise almost verbatim copy of _finishString() - int outPtr = 0; - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - - // Here we do want to do full decoding, hence: - final int[] codes = CharTypes.getInputCodeUtf8(); - final byte[] inputBuffer = _inputBuffer; - - main_loop: - while (true) { - // Then the tight ascii non-funny-char loop: - ascii_loop: - while (true) { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - int max = _inputEnd; - { - int max2 = _inputPtr + (outBuf.length - outPtr); - if (max2 < max) { - max = max2; - } - } - while (_inputPtr < max) { - c = (int) inputBuffer[_inputPtr++] & 0xFF; - if (c == INT_APOSTROPHE || codes[c] != 0) { - break ascii_loop; - } - outBuf[outPtr++] = (char) c; - } - } - - // Ok: end marker, escape or multi-byte? - if (c == INT_APOSTROPHE) { - break main_loop; - } - - switch (codes[c]) { - case 1: // backslash - if (c != INT_QUOTE) { // marked as special, isn't here - c = _decodeEscaped(); - } - break; - case 2: // 2-byte UTF - c = _decodeUtf8_2(c); - break; - case 3: // 3-byte UTF - if ((_inputEnd - _inputPtr) >= 2) { - c = _decodeUtf8_3fast(c); - } else { - c = _decodeUtf8_3(c); - } - break; - case 4: // 4-byte UTF - c = _decodeUtf8_4(c); - // Let's add first part right away: - outBuf[outPtr++] = (char) (0xD800 | (c >> 10)); - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - c = 0xDC00 | (c & 0x3FF); - // And let the other char output down below - break; - default: - if (c < INT_SPACE) { - _throwUnquotedSpace(c, "string value"); - } - // Is this good enough error message? - _reportInvalidChar(c); - } - // Need more room? - if (outPtr >= outBuf.length) { - outBuf = _textBuffer.finishCurrentSegment(); - outPtr = 0; - } - // Ok, let's add char to output: - outBuf[outPtr++] = (char) c; - } - _textBuffer.setCurrentLength(outPtr); - - return JsonToken.VALUE_STRING; - } - - /* - /*************************************************** - /* Internal methods, other parsing helper methods - /*************************************************** - */ - - protected void _matchToken(JsonToken token) - throws IOException, JsonParseException - { - // First char is already matched, need to check the rest - byte[] matchBytes = token.asByteArray(); - int i = 1; - - for (int len = matchBytes.length; i < len; ++i) { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - if (matchBytes[i] != _inputBuffer[_inputPtr]) { - _reportInvalidToken(token.asString().substring(0, i)); - } - ++_inputPtr; - } - /* Ok, fine; let's not bother checking anything beyond keyword. - * If there's something wrong there, it'll cause a parsing - * error later on. - */ - return; - } - - private void _reportInvalidToken(String matchedPart) - throws IOException, JsonParseException - { - StringBuilder sb = new StringBuilder(matchedPart); - /* Let's just try to find what appears to be the token, using - * regular Java identifier character rules. It's just a heuristic, - * nothing fancy here (nor fast). - */ - while (true) { - if (_inputPtr >= _inputEnd && !loadMore()) { - break; - } - int i = (int) _inputBuffer[_inputPtr++]; - char c = (char) _decodeCharForError(i); - if (!Character.isJavaIdentifierPart(c)) { - break; - } - ++_inputPtr; - sb.append(c); - } - - _reportError("Unrecognized token '"+sb.toString()+"': was expecting 'null', 'true' or 'false'"); - } - - /* - /*************************************************** - /* Internal methods, ws skipping, escape/unescape - /*************************************************** - */ - - private final int _skipWS() - throws IOException, JsonParseException - { - while (_inputPtr < _inputEnd || loadMore()) { - int i = _inputBuffer[_inputPtr++] & 0xFF; - if (i > INT_SPACE) { - if (i != INT_SLASH) { - return i; - } - _skipComment(); - } else if (i != INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - } else if (i == INT_CR) { - _skipCR(); - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - throw _constructError("Unexpected end-of-input within/between "+_parsingContext.getTypeDesc()+" entries"); - } - - private final int _skipWSOrEnd() - throws IOException, JsonParseException - { - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = _inputBuffer[_inputPtr++] & 0xFF; - if (i > INT_SPACE) { - if (i != INT_SLASH) { - return i; - } - _skipComment(); - } else if (i != INT_SPACE) { - if (i == INT_LF) { - _skipLF(); - } else if (i == INT_CR) { - _skipCR(); - } else if (i != INT_TAB) { - _throwInvalidSpace(i); - } - } - } - // We ran out of input... - _handleEOF(); - return -1; - } - - private final void _skipComment() - throws IOException, JsonParseException - { - if (!isEnabled(Feature.ALLOW_COMMENTS)) { - _reportUnexpectedChar('/', "maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser)"); - } - // First: check which comment (if either) it is: - if (_inputPtr >= _inputEnd && !loadMore()) { - _reportInvalidEOF(" in a comment"); - } - int c = _inputBuffer[_inputPtr++] & 0xFF; - if (c == INT_SLASH) { - _skipCppComment(); - } else if (c == INT_ASTERISK) { - _skipCComment(); - } else { - _reportUnexpectedChar(c, "was expecting either '*' or '/' for a comment"); - } - } - - private final void _skipCComment() - throws IOException, JsonParseException - { - // Need to be UTF-8 aware here to decode content (for skipping) - final int[] codes = CharTypes.getInputCodeComment(); - - // Ok: need the matching '*/' - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++] & 0xFF; - int code = codes[i]; - if (code != 0) { - switch (code) { - case INT_ASTERISK: - if (_inputBuffer[_inputPtr] == INT_SLASH) { - ++_inputPtr; - return; - } - break; - case INT_LF: - _skipLF(); - break; - case INT_CR: - _skipCR(); - break; - default: // e.g. -1 - // Is this good enough error message? - _reportInvalidChar(i); - } - } - } - _reportInvalidEOF(" in a comment"); - } - - private final void _skipCppComment() - throws IOException, JsonParseException - { - // Ok: need to find EOF or linefeed - final int[] codes = CharTypes.getInputCodeComment(); - while ((_inputPtr < _inputEnd) || loadMore()) { - int i = (int) _inputBuffer[_inputPtr++] & 0xFF; - int code = codes[i]; - if (code != 0) { - switch (code) { - case INT_LF: - _skipLF(); - return; - case INT_CR: - _skipCR(); - return; - case INT_ASTERISK: // nop for these comments - break; - default: // e.g. -1 - // Is this good enough error message? - _reportInvalidChar(i); - } - } - } - } - - protected final char _decodeEscaped() - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in character escape sequence"); - } - } - int c = (int) _inputBuffer[_inputPtr++]; - - switch ((int) c) { - // First, ones that are mapped - case INT_b: - return '\b'; - case INT_t: - return '\t'; - case INT_n: - return '\n'; - case INT_f: - return '\f'; - case INT_r: - return '\r'; - - // And these are to be returned as they are - case INT_QUOTE: - case INT_SLASH: - case INT_BACKSLASH: - return (char) c; - - case INT_u: // and finally hex-escaped - break; - - default: - _reportError("Unrecognized character escape (\\ followed by "+_getCharDesc(_decodeCharForError(c))+")"); - } - - // Ok, a hex escape. Need 4 characters - int value = 0; - for (int i = 0; i < 4; ++i) { - if (_inputPtr >= _inputEnd) { - if (!loadMore()) { - _reportInvalidEOF(" in character escape sequence"); - } - } - int ch = (int) _inputBuffer[_inputPtr++]; - int digit = CharTypes.charToHex(ch); - if (digit < 0) { - _reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence"); - } - value = (value << 4) | digit; - } - return (char) value; - } - - protected int _decodeCharForError(int firstByte) - throws IOException, JsonParseException - { - int c = (int) firstByte; - if (c < 0) { // if >= 0, is ascii and fine as is - int needed; - - // Ok; if we end here, we got multi-byte combination - if ((c & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF) - c &= 0x1F; - needed = 1; - } else if ((c & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF) - c &= 0x0F; - needed = 2; - } else if ((c & 0xF8) == 0xF0) { - // 4 bytes; double-char with surrogates and all... - c &= 0x07; - needed = 3; - } else { - _reportInvalidInitial(c & 0xFF); - needed = 1; // never gets here - } - - int d = nextByte(); - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF); - } - c = (c << 6) | (d & 0x3F); - - if (needed > 1) { // needed == 1 means 2 bytes total - d = nextByte(); // 3rd byte - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF); - } - c = (c << 6) | (d & 0x3F); - if (needed > 2) { // 4 bytes? (need surrogates) - d = nextByte(); - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF); - } - c = (c << 6) | (d & 0x3F); - } - } - } - return c; - } - - /* - /*************************************************** - /* Internal methods,UTF8 decoding - /*************************************************** - */ - - private final int _decodeUtf8_2(int c) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - int d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - return ((c & 0x1F) << 6) | (d & 0x3F); - } - - private final int _decodeUtf8_3(int c1) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c1 &= 0x0F; - int d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - int c = (c1 << 6) | (d & 0x3F); - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - c = (c << 6) | (d & 0x3F); - return c; - } - - private final int _decodeUtf8_3fast(int c1) - throws IOException, JsonParseException - { - c1 &= 0x0F; - int d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - int c = (c1 << 6) | (d & 0x3F); - d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - c = (c << 6) | (d & 0x3F); - return c; - } - - /** - * @return Character value minus 0x10000; this so that caller - * can readily expand it to actual surrogates - */ - private final int _decodeUtf8_4(int c) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - int d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - c = ((c & 0x07) << 6) | (d & 0x3F); - - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - c = (c << 6) | (d & 0x3F); - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - - /* note: won't change it to negative here, since caller - * already knows it'll need a surrogate - */ - return ((c << 6) | (d & 0x3F)) - 0x10000; - } - - private final void _skipUtf8_2(int c) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c = (int) _inputBuffer[_inputPtr++]; - if ((c & 0xC0) != 0x080) { - _reportInvalidOther(c & 0xFF, _inputPtr); - } - } - - /* Alas, can't heavily optimize skipping, since we still have to - * do validity checks... - */ - private final void _skipUtf8_3(int c) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - //c &= 0x0F; - c = (int) _inputBuffer[_inputPtr++]; - if ((c & 0xC0) != 0x080) { - _reportInvalidOther(c & 0xFF, _inputPtr); - } - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - c = (int) _inputBuffer[_inputPtr++]; - if ((c & 0xC0) != 0x080) { - _reportInvalidOther(c & 0xFF, _inputPtr); - } - } - - private final void _skipUtf8_4(int c) - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - int d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - d = (int) _inputBuffer[_inputPtr++]; - if ((d & 0xC0) != 0x080) { - _reportInvalidOther(d & 0xFF, _inputPtr); - } - } - - /* - /*************************************************** - /* Internal methods, input loading - /*************************************************** - */ - - /** - * We actually need to check the character value here - * (to see if we have \n following \r). - * @throws java.io.IOException Undocumented. - */ - protected final void _skipCR() throws IOException - { - if (_inputPtr < _inputEnd || loadMore()) { - if (_inputBuffer[_inputPtr] == BYTE_LF) { - ++_inputPtr; - } - } - ++_currInputRow; - _currInputRowStart = _inputPtr; - } - - protected final void _skipLF() throws IOException - { - ++_currInputRow; - _currInputRowStart = _inputPtr; - } - - private int nextByte() - throws IOException, JsonParseException - { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - return _inputBuffer[_inputPtr++] & 0xFF; - } - - /* - /*************************************************** - /* Internal methods, error reporting - /*************************************************** - */ - - protected void _reportInvalidChar(int c) - throws JsonParseException - { - // Either invalid WS or illegal UTF-8 start char - if (c < INT_SPACE) { - _throwInvalidSpace(c); - } - _reportInvalidInitial(c); - } - - protected void _reportInvalidInitial(int mask) - throws JsonParseException - { - _reportError("Invalid UTF-8 start byte 0x"+Integer.toHexString(mask)); - } - - protected void _reportInvalidOther(int mask) - throws JsonParseException - { - _reportError("Invalid UTF-8 middle byte 0x"+Integer.toHexString(mask)); - } - - protected void _reportInvalidOther(int mask, int ptr) - throws JsonParseException - { - _inputPtr = ptr; - _reportInvalidOther(mask); - } - - public static int[] growArrayBy(int[] arr, int more) - { - if (arr == null) { - return new int[more]; - } - int[] old = arr; - int len = arr.length; - arr = new int[len + more]; - System.arraycopy(old, 0, arr, 0, len); - return arr; - } - - /* - /*************************************************** - /* Binary access - /*************************************************** - */ - - @Override - protected byte[] _decodeBase64(Base64Variant b64variant) - throws IOException, JsonParseException - { - ByteArrayBuilder builder = _getByteArrayBuilder(); - - /* !!! 23-Jan-2009, tatu: There are some potential problems - * with this: - * - * - Escaped chars are not handled. Should they? - */ - - //main_loop: - while (true) { - // first, we'll skip preceding white space, if any - int ch; - do { - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = (int) _inputBuffer[_inputPtr++] & 0xFF; - } while (ch <= INT_SPACE); - int bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { // reached the end, fair and square? - if (ch == INT_QUOTE) { - return builder.toByteArray(); - } - throw reportInvalidChar(b64variant, ch, 0); - } - int decodedData = bits; - - // then second base64 char; can't get padding yet, nor ws - - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - throw reportInvalidChar(b64variant, ch, 1); - } - decodedData = (decodedData << 6) | bits; - - // third base64 char; can be padding, but not ws - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - bits = b64variant.decodeBase64Char(ch); - - // First branch: can get padding (-> 1 byte) - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - throw reportInvalidChar(b64variant, ch, 2); - } - // Ok, must get padding - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - if (!b64variant.usesPaddingChar(ch)) { - throw reportInvalidChar(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'"); - } - // Got 12 bits, only need 8, need to shift - decodedData >>= 4; - builder.append(decodedData); - continue; - } - // Nope, 2 or 3 bytes - decodedData = (decodedData << 6) | bits; - // fourth and last base64 char; can be padding, but not ws - if (_inputPtr >= _inputEnd) { - loadMoreGuaranteed(); - } - ch = _inputBuffer[_inputPtr++] & 0xFF; - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - throw reportInvalidChar(b64variant, ch, 3); - } - /* With padding we only get 2 bytes; but we have - * to shift it a bit so it is identical to triplet - * case with partial output. - * 3 chars gives 3x6 == 18 bits, of which 2 are - * dummies, need to discard: - */ - decodedData >>= 2; - builder.appendTwoBytes(decodedData); - } else { - // otherwise, our triple is now complete - decodedData = (decodedData << 6) | bits; - builder.appendThreeBytes(decodedData); - } - } - } - - protected IllegalArgumentException reportInvalidChar(Base64Variant b64variant, int ch, int bindex) - throws IllegalArgumentException - { - return reportInvalidChar(b64variant, ch, bindex, null); - } - - /** - * @param b64variant Undocumented. - * @param ch Undocumented. - * @param bindex Relative index within base64 character unit; between 0 - * and 3 (as unit has exactly 4 characters) - * @param msg Undocumented. - * @return Undocumented. - */ - protected IllegalArgumentException reportInvalidChar(Base64Variant b64variant, int ch, int bindex, String msg) - throws IllegalArgumentException - { - String base; - if (ch <= INT_SPACE) { - base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units"; - } else if (b64variant.usesPaddingChar(ch)) { - base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character"; - } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) { - // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level) - base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } else { - base = "Illegal character '"+((char)ch)+"' (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } - if (msg != null) { - base = base + ": " + msg; - } - return new IllegalArgumentException(base); - } -} diff --git a/src/org/codehaus/jackson/impl/WriterBasedGenerator.java b/src/org/codehaus/jackson/impl/WriterBasedGenerator.java deleted file mode 100644 index d44264e21e..0000000000 --- a/src/org/codehaus/jackson/impl/WriterBasedGenerator.java +++ /dev/null @@ -1,1023 +0,0 @@ -package org.codehaus.jackson.impl; - -import java.io.*; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.io.*; -import org.codehaus.jackson.util.CharTypes; - -public final class WriterBasedGenerator - extends JsonGeneratorBase -{ - final static int SHORT_WRITE = 32; - - final static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); - - /* - //////////////////////////////////////////////////// - // Configuration - //////////////////////////////////////////////////// - */ - - final protected IOContext _ioContext; - - final protected Writer _writer; - - /* - //////////////////////////////////////////////////// - // Output buffering - //////////////////////////////////////////////////// - */ - - /** - * Intermediate buffer in which contents are buffered before - * being written using {@link #_writer}. - */ - protected char[] _outputBuffer; - - /** - * Pointer to the first buffered character to output - */ - protected int _outputHead = 0; - - /** - * Pointer to the position right beyond the last character to output - * (end marker; may be past the buffer) - */ - protected int _outputTail = 0; - - /** - * End marker of the output buffer; one past the last valid position - * within the buffer. - */ - protected int _outputEnd; - - /** - * 6-char temporary buffer allocated if needed, for constructing - * escape sequences - */ - protected char[] _entityBuffer; - - /* - //////////////////////////////////////////////////// - // Life-cycle - //////////////////////////////////////////////////// - */ - - public WriterBasedGenerator(IOContext ctxt, int features, ObjectCodec codec, - Writer w) - { - super(features, codec); - _ioContext = ctxt; - _writer = w; - _outputBuffer = ctxt.allocConcatBuffer(); - _outputEnd = _outputBuffer.length; - } - - /* - //////////////////////////////////////////////////// - // Output method implementations, structural - //////////////////////////////////////////////////// - */ - - @Override - protected void _writeStartArray() - throws IOException, JsonGenerationException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '['; - } - - @Override - protected void _writeEndArray() - throws IOException, JsonGenerationException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = ']'; - } - - @Override - protected void _writeStartObject() - throws IOException, JsonGenerationException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '{'; - } - - @Override - protected void _writeEndObject() - throws IOException, JsonGenerationException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '}'; - } - - @Override - protected void _writeFieldName(String name, boolean commaBefore) - throws IOException, JsonGenerationException - { - if (_cfgPrettyPrinter != null) { - _writePPFieldName(name, commaBefore); - return; - } - // for fast+std case, need to output up to 2 chars, comma, dquote - if ((_outputTail + 1) >= _outputEnd) { - _flushBuffer(); - } - if (commaBefore) { - _outputBuffer[_outputTail++] = ','; - } - - /* To support [JACKSON-46], we'll do this: - * (Quostion: should quoting of spaces (etc) still be enabled?) - */ - if (!isEnabled(Feature.QUOTE_FIELD_NAMES)) { - _writeString(name); - return; - } - - // we know there's room for at least one more char - _outputBuffer[_outputTail++] = '"'; - // The beef: - _writeString(name); - // and closing quotes; need room for one more char: - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } - - /** - * Specialized version of _writeFieldName, off-lined - * to keep the "fast path" as simple (and hopefully fast) as possible. - * @param name Undocumented. - * @param commaBefore Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - protected final void _writePPFieldName(String name, boolean commaBefore) - throws IOException, JsonGenerationException - { - if (commaBefore) { - _cfgPrettyPrinter.writeObjectEntrySeparator(this); - } else { - _cfgPrettyPrinter.beforeObjectEntries(this); - } - - if (isEnabled(Feature.QUOTE_FIELD_NAMES)) { // standard - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _writeString(name); - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } else { // non-standard, omit quotes - _writeString(name); - } - } - - /* - //////////////////////////////////////////////////// - // Output method implementations, textual - //////////////////////////////////////////////////// - */ - - @Override - public void writeString(String text) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write text value"); - if (text == null) { - _writeNull(); - return; - } - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _writeString(text); - // And finally, closing quotes - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } - - @Override - public void writeString(char[] text, int offset, int len) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write text value"); - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _writeString(text, offset, len); - // And finally, closing quotes - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } - - /* - //////////////////////////////////////////////////// - // Output method implementations, unprocessed ("raw") - //////////////////////////////////////////////////// - */ - - @Override - public void writeRaw(String text) - throws IOException, JsonGenerationException - { - // Nothing to check, can just output as is - int len = text.length(); - int room = _outputEnd - _outputTail; - - if (room == 0) { - _flushBuffer(); - room = _outputEnd - _outputTail; - } - // But would it nicely fit in? If yes, it's easy - if (room >= len) { - text.getChars(0, len, _outputBuffer, _outputTail); - _outputTail += len; - } else { - writeRawLong(text); - } - } - - @Override - public void writeRaw(String text, int start, int len) - throws IOException, JsonGenerationException - { - // Nothing to check, can just output as is - int room = _outputEnd - _outputTail; - - if (room < len) { - _flushBuffer(); - room = _outputEnd - _outputTail; - } - // But would it nicely fit in? If yes, it's easy - if (room >= len) { - text.getChars(start, start+len, _outputBuffer, _outputTail); - _outputTail += len; - } else { - writeRawLong(text.substring(start, start+len)); - } - } - - @Override - public void writeRaw(char[] text, int offset, int len) - throws IOException, JsonGenerationException - { - // Only worth buffering if it's a short write? - if (len < SHORT_WRITE) { - int room = _outputEnd - _outputTail; - if (len > room) { - _flushBuffer(); - } - System.arraycopy(text, offset, _outputBuffer, _outputTail, len); - _outputTail += len; - return; - } - // Otherwise, better just pass through: - _flushBuffer(); - _writer.write(text, offset, len); - } - - @Override - public void writeRaw(char c) - throws IOException, JsonGenerationException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = c; - } - - @Override - public void writeRawValue(String text) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write raw value"); - writeRaw(text); - } - - @Override - public void writeRawValue(String text, int offset, int len) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write raw value"); - writeRaw(text, offset, len); - } - - @Override - public void writeRawValue(char[] text, int offset, int len) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write raw value"); - writeRaw(text, offset, len); - } - - private void writeRawLong(String text) - throws IOException, JsonGenerationException - { - int room = _outputEnd - _outputTail; - // If not, need to do it by looping - text.getChars(0, room, _outputBuffer, _outputTail); - _outputTail += room; - _flushBuffer(); - int offset = room; - int len = text.length() - room; - - while (len > _outputEnd) { - int amount = _outputEnd; - text.getChars(offset, offset+amount, _outputBuffer, 0); - _outputHead = 0; - _outputTail = amount; - _flushBuffer(); - offset += amount; - len -= amount; - } - // And last piece (at most length of buffer) - text.getChars(offset, offset+len, _outputBuffer, 0); - _outputHead = 0; - _outputTail = len; - } - - /* - //////////////////////////////////////////////////// - // Output method implementations, base64-encoded binary - //////////////////////////////////////////////////// - */ - - @Override - public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write binary value"); - // Starting quotes - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _writeBinary(b64variant, data, offset, offset+len); - // and closing quotes - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } - - /* - //////////////////////////////////////////////////// - // Output method implementations, primitive - //////////////////////////////////////////////////// - */ - - @Override - public void writeNumber(int i) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write number"); - // up to 10 digits and possible minus sign - if ((_outputTail + 11) >= _outputEnd) { - _flushBuffer(); - } - if (_cfgNumbersAsStrings) { - _writeQuotedInt(i); - return; - } - _outputTail = NumberOutput.outputInt(i, _outputBuffer, _outputTail); - } - - private final void _writeQuotedInt(int i) throws IOException { - if ((_outputTail + 13) >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _outputTail = NumberOutput.outputInt(i, _outputBuffer, _outputTail); - _outputBuffer[_outputTail++] = '"'; - } - - @Override - public void writeNumber(long l) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write number"); - if (_cfgNumbersAsStrings) { - _writeQuotedLong(l); - return; - } - if ((_outputTail + 21) >= _outputEnd) { - // up to 20 digits, minus sign - _flushBuffer(); - } - _outputTail = NumberOutput.outputLong(l, _outputBuffer, _outputTail); - } - - private final void _writeQuotedLong(long l) throws IOException { - if ((_outputTail + 23) >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - _outputTail = NumberOutput.outputLong(l, _outputBuffer, _outputTail); - _outputBuffer[_outputTail++] = '"'; - } - - // !!! 05-Aug-2008, tatus: Any ways to optimize these? - - @Override - public void writeNumber(BigInteger value) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write number"); - if (value == null) { - _writeNull(); - } else if (_cfgNumbersAsStrings) { - _writeQuotedRaw(value); - } else { - writeRaw(value.toString()); - } - } - - - @Override - public void writeNumber(double d) - throws IOException, JsonGenerationException - { - if (_cfgNumbersAsStrings || - // [JACKSON-139] - (((Double.isNaN(d) || Double.isInfinite(d)) - && isEnabled(Feature.QUOTE_NON_NUMERIC_NUMBERS)))) { - writeString(String.valueOf(d)); - return; - } - // What is the max length for doubles? 40 chars? - _verifyValueWrite("write number"); - writeRaw(String.valueOf(d)); - } - - @Override - public void writeNumber(float f) - throws IOException, JsonGenerationException - { - if (_cfgNumbersAsStrings || - // [JACKSON-139] - (((Float.isNaN(f) || Float.isInfinite(f)) - && isEnabled(Feature.QUOTE_NON_NUMERIC_NUMBERS)))) { - writeString(String.valueOf(f)); - return; - } - // What is the max length for floats? - _verifyValueWrite("write number"); - writeRaw(String.valueOf(f)); - } - - @Override - public void writeNumber(BigDecimal value) - throws IOException, JsonGenerationException - { - // Don't really know max length for big decimal, no point checking - _verifyValueWrite("write number"); - if (value == null) { - _writeNull(); - } else if (_cfgNumbersAsStrings) { - _writeQuotedRaw(value); - } else { - writeRaw(value.toString()); - } - } - - @Override - public void writeNumber(String encodedValue) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write number"); - if (_cfgNumbersAsStrings) { - _writeQuotedRaw(encodedValue); - } else { - writeRaw(encodedValue); - } - } - - private final void _writeQuotedRaw(Object value) throws IOException - { - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - writeRaw(value.toString()); - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail++] = '"'; - } - - @Override - public void writeBoolean(boolean state) - throws IOException, JsonGenerationException - { - _verifyValueWrite("write boolean value"); - if ((_outputTail + 5) >= _outputEnd) { - _flushBuffer(); - } - int ptr = _outputTail; - char[] buf = _outputBuffer; - if (state) { - buf[ptr] = 't'; - buf[++ptr] = 'r'; - buf[++ptr] = 'u'; - buf[++ptr] = 'e'; - } else { - buf[ptr] = 'f'; - buf[++ptr] = 'a'; - buf[++ptr] = 'l'; - buf[++ptr] = 's'; - buf[++ptr] = 'e'; - } - _outputTail = ptr+1; - } - - @Override - public void writeNull() - throws IOException, JsonGenerationException - { - _verifyValueWrite("write null value"); - _writeNull(); - } - - /* - //////////////////////////////////////////////////// - // Implementations for other methods - //////////////////////////////////////////////////// - */ - - @Override - protected final void _verifyValueWrite(String typeMsg) - throws IOException, JsonGenerationException - { - int status = _writeContext.writeValue(); - if (status == JsonWriteContext.STATUS_EXPECT_NAME) { - _reportError("Can not "+typeMsg+", expecting field name"); - } - if (_cfgPrettyPrinter == null) { - char c; - switch (status) { - case JsonWriteContext.STATUS_OK_AFTER_COMMA: - c = ','; - break; - case JsonWriteContext.STATUS_OK_AFTER_COLON: - c = ':'; - break; - case JsonWriteContext.STATUS_OK_AFTER_SPACE: - c = ' '; - break; - case JsonWriteContext.STATUS_OK_AS_IS: - default: - return; - } - if (_outputTail >= _outputEnd) { - _flushBuffer(); - } - _outputBuffer[_outputTail] = c; - ++_outputTail; - return; - } - // Otherwise, pretty printer knows what to do... - _verifyPrettyValueWrite(typeMsg, status); - } - - protected final void _verifyPrettyValueWrite(String typeMsg, int status) - throws IOException, JsonGenerationException - { - // If we have a pretty printer, it knows what to do: - switch (status) { - case JsonWriteContext.STATUS_OK_AFTER_COMMA: // array - _cfgPrettyPrinter.writeArrayValueSeparator(this); - break; - case JsonWriteContext.STATUS_OK_AFTER_COLON: - _cfgPrettyPrinter.writeObjectFieldValueSeparator(this); - break; - case JsonWriteContext.STATUS_OK_AFTER_SPACE: - _cfgPrettyPrinter.writeRootValueSeparator(this); - break; - case JsonWriteContext.STATUS_OK_AS_IS: - // First entry, but of which context? - if (_writeContext.inArray()) { - _cfgPrettyPrinter.beforeArrayValues(this); - } else if (_writeContext.inObject()) { - _cfgPrettyPrinter.beforeObjectEntries(this); - } - break; - default: - _cantHappen(); - break; - } - } - - /* - //////////////////////////////////////////////////// - // Low-level output handling - //////////////////////////////////////////////////// - */ - - @Override - public final void flush() - throws IOException - { - _flushBuffer(); - _writer.flush(); - } - - @Override - public void close() - throws IOException - { - super.close(); - - /* 05-Dec-2008, tatu: To add [JACKSON-27], need to close open - * scopes. - */ - // First: let's see that we still have buffers... - if (_outputBuffer != null - && isEnabled(Feature.AUTO_CLOSE_JSON_CONTENT)) { - while (true) { - JsonStreamContext ctxt = getOutputContext(); - if (ctxt.inArray()) { - writeEndArray(); - } else if (ctxt.inObject()) { - writeEndObject(); - } else { - break; - } - } - } - _flushBuffer(); - - /* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close() - * on the underlying Reader, unless we "own" it, or auto-closing - * feature is enabled. - * One downside: when using UTF8Writer, underlying buffer(s) - * may not be properly recycled if we don't close the writer. - */ - if (_ioContext.isResourceManaged() || isEnabled(Feature.AUTO_CLOSE_TARGET)) { - _writer.close(); - } else { - // If we can't close it, we should at least flush - _writer.flush(); - } - // Internal buffer(s) generator has can now be released as well - _releaseBuffers(); - } - - @Override - protected void _releaseBuffers() - { - char[] buf = _outputBuffer; - if (buf != null) { - _outputBuffer = null; - _ioContext.releaseConcatBuffer(buf); - } - } - - /* - //////////////////////////////////////////////////// - // Internal methods, low-level writing - //////////////////////////////////////////////////// - */ - - private void _writeString(String text) - throws IOException, JsonGenerationException - { - /* One check first: if String won't fit in the buffer, let's - * segment writes. No point in extending buffer to huge sizes - * (like if someone wants to include multi-megabyte base64 - * encoded stuff or such) - */ - int len = text.length(); - if (len > _outputEnd) { // Let's reserve space for entity at begin/end - _writeLongString(text); - return; - } - - // Ok: we know String will fit in buffer ok - // But do we need to flush first? - if ((_outputTail + len) > _outputEnd) { - _flushBuffer(); - } - text.getChars(0, len, _outputBuffer, _outputTail); - - // And then we'll need to verify need for escaping etc: - int end = _outputTail + len; - final int[] escCodes = CharTypes.getOutputEscapes(); - final int escLen = escCodes.length; - - output_loop: - while (_outputTail < end) { - // Fast loop for chars not needing escaping - escape_loop: - while (true) { - char c = _outputBuffer[_outputTail]; - if (c < escLen && escCodes[c] != 0) { - break escape_loop; - } - if (++_outputTail >= end) { - break output_loop; - } - } - - // Ok, bumped into something that needs escaping. - /* First things first: need to flush the buffer. - * Inlined, as we don't want to lose tail pointer - */ - int flushLen = (_outputTail - _outputHead); - if (flushLen > 0) { - _writer.write(_outputBuffer, _outputHead, flushLen); - } - /* In any case, tail will be the new start, so hopefully - * we have room now. - */ - { - int escCode = escCodes[_outputBuffer[_outputTail]]; - ++_outputTail; - int needLen = (escCode < 0) ? 6 : 2; - // If not, need to call separate method (note: buffer is empty now) - if (needLen > _outputTail) { - _outputHead = _outputTail; - _writeSingleEscape(escCode); - } else { - // But if it fits, can just prepend to buffer - int ptr = _outputTail - needLen; - _outputHead = ptr; - _appendSingleEscape(escCode, _outputBuffer, ptr); - } - } - } - } - - /** - * Method called to write "long strings", strings whose length exceeds - * output buffer length. - */ - private void _writeLongString(String text) - throws IOException, JsonGenerationException - { - // First things first: let's flush the buffer to get some more room - _flushBuffer(); - - // Then we can write - final int textLen = text.length(); - int offset = 0; - do { - int max = _outputEnd; - int segmentLen = ((offset + max) > textLen) - ? (textLen - offset) : max; - text.getChars(offset, offset+segmentLen, _outputBuffer, 0); - _writeSegment(segmentLen); - offset += segmentLen; - } while (offset < textLen); - } - /** - * Method called to output textual context which has been copied - * to the output buffer prior to call. If any escaping is needed, - * it will also be handled by the method. - *

- * Note: when called, textual content to write is within output - * buffer, right after buffered content (if any). That's why only - * length of that text is passed, as buffer and offset are implied. - */ - private final void _writeSegment(int end) - throws IOException, JsonGenerationException - { - final int[] escCodes = CharTypes.getOutputEscapes(); - final int escLen = escCodes.length; - - int ptr = 0; - - output_loop: - while (ptr < end) { - // Fast loop for chars not needing escaping - int start = ptr; - while (true) { - char c = _outputBuffer[ptr]; - if (c < escLen && escCodes[c] != 0) { - break; - } - if (++ptr >= end) { - break; - } - } - - // Ok, bumped into something that needs escaping. - /* First things first: need to flush the buffer. - * Inlined, as we don't want to lose tail pointer - */ - int flushLen = (ptr - start); - if (flushLen > 0) { - _writer.write(_outputBuffer, start, flushLen); - if (ptr >= end) { - break output_loop; - } - } - /* In any case, tail will be the new start, so hopefully - * we have room now. - */ - { - int escCode = escCodes[_outputBuffer[ptr]]; - ++ptr; - int needLen = (escCode < 0) ? 6 : 2; - // If not, need to call separate method (note: buffer is empty now) - if (needLen > _outputTail) { - _writeSingleEscape(escCode); - } else { - // But if it fits, can just prepend to buffer - ptr -= needLen; - _appendSingleEscape(escCode, _outputBuffer, ptr); - } - } - } - } - - /** - * This method called when the string content is already in - * a char buffer, and need not be copied for processing. - */ - private void _writeString(char[] text, int offset, int len) - throws IOException, JsonGenerationException - { - /* Let's just find longest spans of non-escapable - * content, and for each see if it makes sense - * to copy them, or write through - */ - len += offset; // -> len marks the end from now on - final int[] escCodes = CharTypes.getOutputEscapes(); - final int escLen = escCodes.length; - while (offset < len) { - int start = offset; - - while (true) { - char c = text[offset]; - if (c < escLen && escCodes[c] != 0) { - break; - } - if (++offset >= len) { - break; - } - } - - // Short span? Better just copy it to buffer first: - int newAmount = offset - start; - if (newAmount < SHORT_WRITE) { - // Note: let's reserve room for escaped char (up to 6 chars) - if ((_outputTail + newAmount) > _outputEnd) { - _flushBuffer(); - } - if (newAmount > 0) { - System.arraycopy(text, start, _outputBuffer, _outputTail, newAmount); - _outputTail += newAmount; - } - } else { // Nope: better just write through - _flushBuffer(); - _writer.write(text, start, newAmount); - } - // Was this the end? - if (offset >= len) { // yup - break; - } - // Nope, need to escape the char. - int escCode = escCodes[text[offset]]; - ++offset; - int needLen = (escCode < 0) ? 6 : 2; - if ((_outputTail + needLen) > _outputEnd) { - _flushBuffer(); - } - _appendSingleEscape(escCode, _outputBuffer, _outputTail); - _outputTail += needLen; - } - } - - protected void _writeBinary(Base64Variant b64variant, byte[] input, int inputPtr, final int inputEnd) - throws IOException, JsonGenerationException - { - // Encoding is by chunks of 3 input, 4 output chars, so: - int safeInputEnd = inputEnd - 3; - // Let's also reserve room for possible (and quoted) lf char each round - int safeOutputEnd = _outputEnd - 6; - int chunksBeforeLF = b64variant.getMaxLineLength() >> 2; - - // Ok, first we loop through all full triplets of data: - while (inputPtr <= safeInputEnd) { - if (_outputTail > safeOutputEnd) { // need to flush - _flushBuffer(); - } - // First, mash 3 bytes into lsb of 32-bit int - int b24 = ((int) input[inputPtr++]) << 8; - b24 |= ((int) input[inputPtr++]) & 0xFF; - b24 = (b24 << 8) | (((int) input[inputPtr++]) & 0xFF); - _outputTail = b64variant.encodeBase64Chunk(b24, _outputBuffer, _outputTail); - if (--chunksBeforeLF <= 0) { - // note: must quote in JSON value - _outputBuffer[_outputTail++] = '\\'; - _outputBuffer[_outputTail++] = 'n'; - chunksBeforeLF = b64variant.getMaxLineLength() >> 2; - } - } - - // And then we may have 1 or 2 leftover bytes to encode - int inputLeft = inputEnd - inputPtr; // 0, 1 or 2 - if (inputLeft > 0) { // yes, but do we have room for output? - if (_outputTail > safeOutputEnd) { // don't really need 6 bytes but... - _flushBuffer(); - } - int b24 = ((int) input[inputPtr++]) << 16; - if (inputLeft == 2) { - b24 |= (((int) input[inputPtr++]) & 0xFF) << 8; - } - _outputTail = b64variant.encodeBase64Partial(b24, inputLeft, _outputBuffer, _outputTail); - } - } - - private final void _writeNull() throws IOException - { - if ((_outputTail + 4) >= _outputEnd) { - _flushBuffer(); - } - int ptr = _outputTail; - char[] buf = _outputBuffer; - buf[ptr] = 'n'; - buf[++ptr] = 'u'; - buf[++ptr] = 'l'; - buf[++ptr] = 'l'; - _outputTail = ptr+1; - } - - /** - * @param escCode Character code for escape sequence (\C); or -1 - * to indicate a generic (\\uXXXX) sequence. - */ - private void _writeSingleEscape(int escCode) - throws IOException - { - char[] buf = _entityBuffer; - if (buf == null) { - buf = new char[6]; - buf[0] = '\\'; - buf[2] = '0'; - buf[3] = '0'; - } - - if (escCode < 0) { // control char, value -(char + 1) - int value = -(escCode + 1); - buf[1] = 'u'; - // We know it's a control char, so only the last 2 chars are non-0 - buf[4] = HEX_CHARS[value >> 4]; - buf[5] = HEX_CHARS[value & 0xF]; - _writer.write(buf, 0, 6); - } else { - buf[1] = (char) escCode; - _writer.write(buf, 0, 2); - } - } - - private void _appendSingleEscape(int escCode, char[] buf, int ptr) - { - if (escCode < 0) { // control char, value -(char + 1) - int value = -(escCode + 1); - buf[ptr] = '\\'; - buf[++ptr] = 'u'; - // We know it's a control char, so only the last 2 chars are non-0 - buf[++ptr] = '0'; - buf[++ptr] = '0'; - buf[++ptr] = HEX_CHARS[value >> 4]; - buf[++ptr] = HEX_CHARS[value & 0xF]; - } else { - buf[ptr] = '\\'; - buf[ptr+1] = (char) escCode; - } - } - - protected final void _flushBuffer() throws IOException - { - int len = _outputTail - _outputHead; - if (len > 0) { - int offset = _outputHead; - _outputTail = _outputHead = 0; - _writer.write(_outputBuffer, offset, len); - } - } -} diff --git a/src/org/codehaus/jackson/io/BaseReader.java b/src/org/codehaus/jackson/io/BaseReader.java deleted file mode 100644 index b0fb6417be..0000000000 --- a/src/org/codehaus/jackson/io/BaseReader.java +++ /dev/null @@ -1,117 +0,0 @@ - -package org.codehaus.jackson.io; - -import java.io.*; - - -/** - * Simple basic class for optimized readers in this package; implements - * "cookie-cutter" methods that are used by all actual implementations. - */ -abstract class BaseReader - extends Reader -{ - /** - * JSON actually limits available Unicode range in the high end - * to the same as xml (to basically limit UTF-8 max byte sequence - * length to 4) - */ - final protected static int LAST_VALID_UNICODE_CHAR = 0x10FFFF; - - final protected static char NULL_CHAR = (char) 0; - final protected static char NULL_BYTE = (byte) 0; - - final protected IOContext mContext; - - protected InputStream mIn; - - protected byte[] mBuffer; - - protected int mPtr; - protected int mLength; - - /* - //////////////////////////////////////// - // Life-cycle - //////////////////////////////////////// - */ - - protected BaseReader(IOContext context, - InputStream in, byte[] buf, int ptr, int len) - { - mContext = context; - mIn = in; - mBuffer = buf; - mPtr = ptr; - mLength = len; - } - - /* - //////////////////////////////////////// - // Reader API - //////////////////////////////////////// - */ - - public void close() - throws IOException - { - InputStream in = mIn; - - if (in != null) { - mIn = null; - freeBuffers(); - in.close(); - } - } - - char[] mTmpBuf = null; - - /** - * Although this method is implemented by the base class, AND it should - * never be called by main code, let's still implement it bit more - * efficiently just in case - */ - public int read() - throws IOException - { - if (mTmpBuf == null) { - mTmpBuf = new char[1]; - } - if (read(mTmpBuf, 0, 1) < 1) { - return -1; - } - return mTmpBuf[0]; - } - - /* - //////////////////////////////////////// - // Internal/package methods: - //////////////////////////////////////// - */ - - /** - * This method should be called along with (or instead of) normal - * close. After calling this method, no further reads should be tried. - * Method will try to recycle read buffers (if any). - */ - public final void freeBuffers() - { - byte[] buf = mBuffer; - if (buf != null) { - mBuffer = null; - mContext.releaseReadIOBuffer(buf); - } - } - - protected void reportBounds(char[] cbuf, int start, int len) - throws IOException - { - throw new ArrayIndexOutOfBoundsException("read(buf,"+start+","+len+"), cbuf["+cbuf.length+"]"); - } - - protected void reportStrangeStream() - throws IOException - { - throw new IOException("Strange I/O stream, returned 0 bytes on read"); - } -} diff --git a/src/org/codehaus/jackson/io/IOContext.java b/src/org/codehaus/jackson/io/IOContext.java deleted file mode 100644 index 874cf6a8f6..0000000000 --- a/src/org/codehaus/jackson/io/IOContext.java +++ /dev/null @@ -1,241 +0,0 @@ -package org.codehaus.jackson.io; - -import org.codehaus.jackson.JsonEncoding; -import org.codehaus.jackson.util.BufferRecycler; -import org.codehaus.jackson.util.TextBuffer; - -/** - * To limit number of configuration and state objects to pass, all - * contextual objects that need to be passed by the factory to - * readers and writers are combined under this object. One instance - * is created for each reader and writer. - */ -public final class IOContext -{ - /* - ////////////////////////////////////////////////////// - // Configuration - ////////////////////////////////////////////////////// - */ - - /** - * Reference to the source object, which can be used for displaying - * location information - */ - final Object _sourceRef; - - /** - * Encoding used by the underlying stream, if known. - */ - protected JsonEncoding _encoding; - - /** - * Flag that indicates whether underlying input/output source/target - * object is fully managed by the owner of this context (parser or - * generator). If true, it is, and is to be closed by parser/generator; - * if false, calling application has to do closing (unless auto-closing - * feature is enabled for the parser/generator in question; in which - * case it acts like the owner). - */ - protected final boolean _managedResource; - - /* - ////////////////////////////////////////////////////// - // Buffer handling, recycling - ////////////////////////////////////////////////////// - */ - - /** - * Recycler used for actual allocation/deallocation/reuse - */ - final BufferRecycler _bufferRecycler; - - /** - * Reference to the allocated I/O buffer for low-level input reading, - * if any allocated. - */ - protected byte[] _readIOBuffer = null; - - /** - * Reference to the allocated I/O buffer used for low-level - * encoding-related buffering. - */ - protected byte[] _writeEncodingBuffer = null; - - /** - * Reference to the buffer allocated for tokenization purposes, - * in which character input is read, and from which it can be - * further returned. - */ - protected char[] _tokenCBuffer = null; - - /** - * Reference to the buffer allocated for buffering it for - * output, before being encoded: generally this means concatenating - * output, then encoding when buffer fills up. - */ - protected char[] _concatCBuffer = null; - - /** - * Reference temporary buffer Parser instances need if calling - * app decides it wants to access name via 'getTextCharacters' method. - * Regular text buffer can not be used as it may contain textual - * representation of the value token. - */ - protected char[] _nameCopyBuffer = null; - - /* - ////////////////////////////////////////////////////// - // Life-cycle - ////////////////////////////////////////////////////// - */ - - public IOContext(BufferRecycler br, Object sourceRef, boolean managedResource) - { - _bufferRecycler = br; - _sourceRef = sourceRef; - _managedResource = managedResource; - } - - public void setEncoding(JsonEncoding enc) - { - _encoding = enc; - } - - /* - ////////////////////////////////////////////////////// - // Public API, accessors - ////////////////////////////////////////////////////// - */ - - public Object getSourceReference() { return _sourceRef; } - public JsonEncoding getEncoding() { return _encoding; } - public boolean isResourceManaged() { return _managedResource; } - - /* - ////////////////////////////////////////////////////// - // Public API, buffer management - ////////////////////////////////////////////////////// - */ - - public TextBuffer constructTextBuffer() - { - return new TextBuffer(_bufferRecycler); - } - - /** - *

- * Note: the method can only be called once during its life cycle.This is to protect against accidental sharing. - * @return Undocumented. - */ - public byte[] allocReadIOBuffer() - { - if (_readIOBuffer != null) { - throw new IllegalStateException("Trying to call allocReadIOBuffer() second time"); - } - _readIOBuffer = _bufferRecycler.allocByteBuffer(BufferRecycler.ByteBufferType.READ_IO_BUFFER); - return _readIOBuffer; - } - - public byte[] allocWriteEncodingBuffer() - { - if (_writeEncodingBuffer != null) { - throw new IllegalStateException("Trying to call allocWriteEncodingBuffer() second time"); - } - _writeEncodingBuffer = _bufferRecycler.allocByteBuffer(BufferRecycler.ByteBufferType.WRITE_ENCODING_BUFFER); - return _writeEncodingBuffer; - } - - public char[] allocTokenBuffer() - { - if (_tokenCBuffer != null) { - throw new IllegalStateException("Trying to call allocTokenBuffer() second time"); - } - _tokenCBuffer = _bufferRecycler.allocCharBuffer(BufferRecycler.CharBufferType.TOKEN_BUFFER); - return _tokenCBuffer; - } - - public char[] allocConcatBuffer() - { - if (_concatCBuffer != null) { - throw new IllegalStateException("Trying to call allocConcatBuffer() second time"); - } - _concatCBuffer = _bufferRecycler.allocCharBuffer(BufferRecycler.CharBufferType.CONCAT_BUFFER); - return _concatCBuffer; - } - - public char[] allocNameCopyBuffer(int minSize) - { - if (_nameCopyBuffer != null) { - throw new IllegalStateException("Trying to call allocNameCopyBuffer() second time"); - } - _nameCopyBuffer = _bufferRecycler.allocCharBuffer(BufferRecycler.CharBufferType.NAME_COPY_BUFFER, minSize); - return _nameCopyBuffer; - } - - /** - * Method to call when all the processing buffers can be safely - * recycled. - * @param buf Undocumented. - */ - public void releaseReadIOBuffer(byte[] buf) - { - if (buf != null) { - /* Let's do sanity checks to ensure once-and-only-once release, - * as well as avoiding trying to release buffers not owned - */ - if (buf != _readIOBuffer) { - throw new IllegalArgumentException("Trying to release buffer not owned by the context"); - } - _readIOBuffer = null; - _bufferRecycler.releaseByteBuffer(BufferRecycler.ByteBufferType.READ_IO_BUFFER, buf); - } - } - - public void releaseWriteEncodingBuffer(byte[] buf) - { - if (buf != null) { - /* Let's do sanity checks to ensure once-and-only-once release, - * as well as avoiding trying to release buffers not owned - */ - if (buf != _writeEncodingBuffer) { - throw new IllegalArgumentException("Trying to release buffer not owned by the context"); - } - _writeEncodingBuffer = null; - _bufferRecycler.releaseByteBuffer(BufferRecycler.ByteBufferType.WRITE_ENCODING_BUFFER, buf); - } - } - - public void releaseTokenBuffer(char[] buf) - { - if (buf != null) { - if (buf != _tokenCBuffer) { - throw new IllegalArgumentException("Trying to release buffer not owned by the context"); - } - _tokenCBuffer = null; - _bufferRecycler.releaseCharBuffer(BufferRecycler.CharBufferType.TOKEN_BUFFER, buf); - } - } - - public void releaseConcatBuffer(char[] buf) - { - if (buf != null) { - if (buf != _concatCBuffer) { - throw new IllegalArgumentException("Trying to release buffer not owned by the context"); - } - _concatCBuffer = null; - _bufferRecycler.releaseCharBuffer(BufferRecycler.CharBufferType.CONCAT_BUFFER, buf); - } - } - - public void releaseNameCopyBuffer(char[] buf) - { - if (buf != null) { - if (buf != _nameCopyBuffer) { - throw new IllegalArgumentException("Trying to release buffer not owned by the context"); - } - _nameCopyBuffer = null; - _bufferRecycler.releaseCharBuffer(BufferRecycler.CharBufferType.NAME_COPY_BUFFER, buf); - } - } -} diff --git a/src/org/codehaus/jackson/io/MergedStream.java b/src/org/codehaus/jackson/io/MergedStream.java deleted file mode 100644 index 7ec3694d85..0000000000 --- a/src/org/codehaus/jackson/io/MergedStream.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.codehaus.jackson.io; - -import java.io.*; - -/** - * Simple {@link InputStream} implementation that is used to "unwind" some - * data previously read from an input stream; so that as long as some of - * that data remains, it's returned; but as long as it's read, we'll - * just use data from the underlying original stream. - * This is similar to {@link java.io.PushbackInputStream}, but here there's - * only one implicit pushback, when instance is constructed. - */ -public final class MergedStream - extends InputStream -{ - final protected IOContext _context; - - final InputStream _in; - - byte[] _buffer; - - int _ptr; - - final int _end; - - public MergedStream(IOContext context, - InputStream in, byte[] buf, int start, int end) - { - _context = context; - _in = in; - _buffer = buf; - _ptr = start; - _end = end; - } - - public int available() - throws IOException - { - if (_buffer != null) { - return _end - _ptr; - } - return _in.available(); - } - - public void close() - throws IOException - { - freeMergedBuffer(); - _in.close(); - } - - public void mark(int readlimit) - { - if (_buffer == null) { - _in.mark(readlimit); - } - } - - public boolean markSupported() - { - // Only supports marks past the initial rewindable section... - return (_buffer == null) && _in.markSupported(); - } - - public int read() - throws IOException - { - if (_buffer != null) { - int c = _buffer[_ptr++] & 0xFF; - if (_ptr >= _end) { - freeMergedBuffer(); - } - return c; - } - return _in.read(); - } - - public int read(byte[] b) - throws IOException - { - return read(b, 0, b.length); - } - - public int read(byte[] b, int off, int len) - throws IOException - { - if (_buffer != null) { - int avail = _end - _ptr; - if (len > avail) { - len = avail; - } - System.arraycopy(_buffer, _ptr, b, off, len); - _ptr += len; - if (_ptr >= _end) { - freeMergedBuffer(); - } - return len; - } - return _in.read(b, off, len); - } - - public void reset() - throws IOException - { - if (_buffer == null) { - _in.reset(); - } - } - - public long skip(long n) - throws IOException - { - long count = 0L; - - if (_buffer != null) { - int amount = _end - _ptr; - - if (amount > n) { // all in pushed back segment? - _ptr += (int) n; - return n; - } - freeMergedBuffer(); - count += amount; - n -= amount; - } - - if (n > 0) { - count += _in.skip(n); - } - return count; - } - - private void freeMergedBuffer() - { - byte[] buf = _buffer; - if (buf != null) { - _buffer = null; - _context.releaseReadIOBuffer(buf); - } - } -} diff --git a/src/org/codehaus/jackson/io/NumberInput.java b/src/org/codehaus/jackson/io/NumberInput.java deleted file mode 100644 index 4ed9b990e0..0000000000 --- a/src/org/codehaus/jackson/io/NumberInput.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.codehaus.jackson.io; - -public final class NumberInput -{ - /** - * Constants needed for parsing longs from basic int parsing methods - */ - final static long L_BILLION = 1000000000; - - final static String MIN_LONG_STR_NO_SIGN = String.valueOf(Long.MIN_VALUE).substring(1); - final static String MAX_LONG_STR = String.valueOf(Long.MAX_VALUE); - - /** - * Fast method for parsing integers that are known to fit into regular 32-bit signed int type.This means that length - * is between 1 and 9 digits (inclusive) - *

- * Note: public to let unit tests call it - * - * @param digitChars Undocumented. - * @param offset Undocumented. - * @param len Undocumented. - * @return Undocumented. - */ - public final static int parseInt(char[] digitChars, int offset, int len) - { - int num = digitChars[offset] - '0'; - len += offset; - // This looks ugly, but appears the fastest way: - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - if (++offset < len) { - num = (num * 10) + (digitChars[offset] - '0'); - } - } - } - } - } - } - } - } - return num; - } - - public final static long parseLong(char[] digitChars, int offset, int len) - { - // Note: caller must ensure length is [10, 18] - int len1 = len-9; - long val = parseInt(digitChars, offset, len1) * L_BILLION; - return val + (long) parseInt(digitChars, offset+len1, 9); - } - - /** - * Helper method for determining if given String representation of an integral number would fit in 64-bit Java long - * or not.Note that input String must NOT contain leading minus sign (even if 'negative' is set to true). - * - * @param digitChars Undocumented. - * @param offset Undocumented. - * @param len Undocumented. - * @param negative Whether original number had a minus sign (which is NOT passed to this method) or not - * @return Undocumented. - */ - public final static boolean inLongRange(char[] digitChars, int offset, int len, - boolean negative) - { - String cmpStr = negative ? MIN_LONG_STR_NO_SIGN : MAX_LONG_STR; - int cmpLen = cmpStr.length(); - if (len < cmpLen) return true; - if (len > cmpLen) return false; - - for (int i = 0; i < cmpLen; ++i) { - if (digitChars[offset+i] > cmpStr.charAt(i)) { - return false; - } - } - return true; - } - - /** - * Similar to {@link #inLongRange(char[],int,int,boolean)}, but - * with String argument - * - * @param numberStr Undocumented. - * @param negative Whether original number had a minus sign (which is - * NOT passed to this method) or not - * @return Undocumented. - * - * @since 1.5.0 - */ - public final static boolean inLongRange(String numberStr, boolean negative) - { - String cmpStr = negative ? MIN_LONG_STR_NO_SIGN : MAX_LONG_STR; - int cmpLen = cmpStr.length(); - int actualLen = numberStr.length(); - if (actualLen < cmpLen) return true; - if (actualLen > cmpLen) return false; - - // could perhaps just use String.compareTo()? - for (int i = 0; i < cmpLen; ++i) { - if (numberStr.charAt(i) > cmpStr.charAt(i)) { - return false; - } - } - return true; - } -} diff --git a/src/org/codehaus/jackson/io/NumberOutput.java b/src/org/codehaus/jackson/io/NumberOutput.java deleted file mode 100644 index 8032be5ac7..0000000000 --- a/src/org/codehaus/jackson/io/NumberOutput.java +++ /dev/null @@ -1,275 +0,0 @@ -package org.codehaus.jackson.io; - -public final class NumberOutput -{ - private final static char NULL_CHAR = (char) 0; - - private static int MILLION = 1000000; - private static int BILLION = 1000000000; - private static long TEN_BILLION_L = 10000000000L; - private static long THOUSAND_L = 1000L; - - private static long MIN_INT_AS_LONG = (long) Integer.MIN_VALUE; - private static long MAX_INT_AS_LONG = (long) Integer.MAX_VALUE; - - final static String SMALLEST_LONG = String.valueOf(Long.MIN_VALUE); - - final static char[] LEADING_TRIPLETS = new char[4000]; - final static char[] FULL_TRIPLETS = new char[4000]; - static { - /* Let's fill it with NULLs for ignorable leading digits, - * and digit chars for others - */ - int ix = 0; - for (int i1 = 0; i1 < 10; ++i1) { - char f1 = (char) ('0' + i1); - char l1 = (i1 == 0) ? NULL_CHAR : f1; - for (int i2 = 0; i2 < 10; ++i2) { - char f2 = (char) ('0' + i2); - char l2 = (i1 == 0 && i2 == 0) ? NULL_CHAR : f2; - for (int i3 = 0; i3 < 10; ++i3) { - // Last is never to be empty - char f3 = (char) ('0' + i3); - LEADING_TRIPLETS[ix] = l1; - LEADING_TRIPLETS[ix+1] = l2; - LEADING_TRIPLETS[ix+2] = f3; - FULL_TRIPLETS[ix] = f1; - FULL_TRIPLETS[ix+1] = f2; - FULL_TRIPLETS[ix+2] = f3; - ix += 4; - } - } - } - } - - final static String[] sSmallIntStrs = new String[] { - "0","1","2","3","4","5","6","7","8","9","10" - }; - final static String[] sSmallIntStrs2 = new String[] { - "-1","-2","-3","-4","-5","-6","-7","-8","-9","-10" - }; - - /* - //////////////////////////////////////////////////// - // Efficient serialization methods using raw buffers - //////////////////////////////////////////////////// - */ - - /** - * @param value Undocumented. - * @param buffer Undocumented. - * @param offset Undocumented. - * @return Offset within buffer after outputting int - */ - public static int outputInt(int value, char[] buffer, int offset) - { - if (value < 0) { - if (value == Integer.MIN_VALUE) { - /* Special case: no matching positive value within range; - * let's then "upgrade" to long and output as such. - */ - return outputLong((long) value, buffer, offset); - } - buffer[offset++] = '-'; - value = -value; - } - - if (value < MILLION) { // at most 2 triplets... - if (value < 1000) { - if (value < 10) { - buffer[offset++] = (char) ('0' + value); - } else { - offset = outputLeadingTriplet(value, buffer, offset); - } - } else { - int thousands = value / 1000; - value -= (thousands * 1000); // == value % 1000 - offset = outputLeadingTriplet(thousands, buffer, offset); - offset = outputFullTriplet(value, buffer, offset); - } - return offset; - } - - // ok, all 3 triplets included - /* Let's first hand possible billions separately before - * handling 3 triplets. This is possible since we know we - * can have at most '2' as billion count. - */ - boolean hasBillions = (value >= BILLION); - if (hasBillions) { - value -= BILLION; - if (value >= BILLION) { - value -= BILLION; - buffer[offset++] = '2'; - } else { - buffer[offset++] = '1'; - } - } - int newValue = value / 1000; - int ones = (value - (newValue * 1000)); // == value % 1000 - value = newValue; - newValue /= 1000; - int thousands = (value - (newValue * 1000)); - - // value now has millions, which have 1, 2 or 3 digits - if (hasBillions) { - offset = outputFullTriplet(newValue, buffer, offset); - } else { - offset = outputLeadingTriplet(newValue, buffer, offset); - } - offset = outputFullTriplet(thousands, buffer, offset); - offset = outputFullTriplet(ones, buffer, offset); - return offset; - } - - /** - * @param value Undocumented. - * @param buffer Undocumented. - * @param offset Undocumented. - * @return Offset within buffer after outputting int - */ - public static int outputLong(long value, char[] buffer, int offset) - { - // First: does it actually fit in an int? - if (value < 0L) { - /* MIN_INT is actually printed as long, just because its - * negation is not an int but long - */ - if (value > MIN_INT_AS_LONG) { - return outputInt((int) value, buffer, offset); - } - if (value == Long.MIN_VALUE) { - // Special case: no matching positive value within range - int len = SMALLEST_LONG.length(); - SMALLEST_LONG.getChars(0, len, buffer, offset); - return (offset + len); - } - buffer[offset++] = '-'; - value = -value; - } else { - if (value <= MAX_INT_AS_LONG) { - return outputInt((int) value, buffer, offset); - } - } - - /* Ok: real long print. Need to first figure out length - * in characters, and then print in from end to beginning - */ - int origOffset = offset; - offset += calcLongStrLength(value); - int ptr = offset; - - // First, with long arithmetics: - while (value > MAX_INT_AS_LONG) { // full triplet - ptr -= 3; - long newValue = value / THOUSAND_L; - int triplet = (int) (value - newValue * THOUSAND_L); - outputFullTriplet(triplet, buffer, ptr); - value = newValue; - } - // Then with int arithmetics: - int ivalue = (int) value; - while (ivalue >= 1000) { // still full triplet - ptr -= 3; - int newValue = ivalue / 1000; - int triplet = ivalue - (newValue * 1000); - outputFullTriplet(triplet, buffer, ptr); - ivalue = newValue; - } - // And finally, if anything remains, partial triplet - outputLeadingTriplet(ivalue, buffer, origOffset); - - return offset; - } - - /* - //////////////////////////////////////////////////// - // Secondary convenience serialization methods - //////////////////////////////////////////////////// - */ - - /* !!! 05-Aug-2008, tatus: Any ways to further optimize - * these? (or need: only called by diagnostics methods?) - */ - - public static String toString(int value) - { - // Lookup table for small values - if (value < sSmallIntStrs.length) { - if (value >= 0) { - return sSmallIntStrs[value]; - } - int v2 = -value - 1; - if (v2 < sSmallIntStrs2.length) { - return sSmallIntStrs2[v2]; - } - } - return Integer.toString(value); - } - - public static String toString(long value) - { - if (value <= Integer.MAX_VALUE && - value >= Integer.MIN_VALUE) { - return toString((int) value); - } - return Long.toString(value); - } - - public static String toString(double value) - { - return Double.toString(value); - } - - /* - //////////////////////////////////////// - // Internal methods - //////////////////////////////////////// - */ - - private static int outputLeadingTriplet(int triplet, char[] buffer, int offset) - { - int digitOffset = (triplet << 2); - char c = LEADING_TRIPLETS[digitOffset++]; - if (c != NULL_CHAR) { - buffer[offset++] = c; - } - c = LEADING_TRIPLETS[digitOffset++]; - if (c != NULL_CHAR) { - buffer[offset++] = c; - } - // Last is required to be non-empty - buffer[offset++] = LEADING_TRIPLETS[digitOffset]; - return offset; - } - - private static int outputFullTriplet(int triplet, char[] buffer, int offset) - { - int digitOffset = (triplet << 2); - buffer[offset++] = FULL_TRIPLETS[digitOffset++]; - buffer[offset++] = FULL_TRIPLETS[digitOffset++]; - buffer[offset++] = FULL_TRIPLETS[digitOffset]; - return offset; - } - - /** - *

- * Pre-conditions: posValue is positive, and larger than - * Integer.MAX_VALUE (about 2 billions). - */ - private static int calcLongStrLength(long posValue) - { - int len = 10; - long comp = TEN_BILLION_L; - - // 19 is longest, need to worry about overflow - while (posValue >= comp) { - if (len == 19) { - break; - } - ++len; - comp = (comp << 3) + (comp << 1); // 10x - } - return len; - } -} diff --git a/src/org/codehaus/jackson/io/SegmentedStringWriter.java b/src/org/codehaus/jackson/io/SegmentedStringWriter.java deleted file mode 100644 index 1fce7026f5..0000000000 --- a/src/org/codehaus/jackson/io/SegmentedStringWriter.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.codehaus.jackson.io; - -import java.io.*; - -import org.codehaus.jackson.util.BufferRecycler; -import org.codehaus.jackson.util.TextBuffer; - -/** - * Efficient alternative to {@link StringWriter}, based on using segmented - * internal buffer. Initial input buffer is also recyclable. - *

- * This class is most useful when serializing JSON content as a String: - * if so, instance of this class can be given as the writer to - * JsonGenerator. - * - * @since 1.3 - */ -public final class SegmentedStringWriter - extends Writer -{ - final TextBuffer _buffer; - - public SegmentedStringWriter(BufferRecycler br) - { - super(); - _buffer = new TextBuffer(br); - } - - /* - ///////////////////////////////////////////////////////////// - // java.io.Writer implementation - ///////////////////////////////////////////////////////////// - */ - - @Override - public Writer append(char c) - { - write(c); - return this; - } - - @Override - public Writer append(CharSequence csq) - { - String str = csq.toString(); - _buffer.append(str, 0, str.length()); - return this; - } - - @Override - public Writer append(CharSequence csq, int start, int end) - { - String str = csq.subSequence(start, end).toString(); - _buffer.append(str, 0, str.length()); - return this; - } - - @Override public void close() { } // NOP - - @Override public void flush() { } // NOP - - @Override - public void write(char[] cbuf) { - _buffer.append(cbuf, 0, cbuf.length); - } - - @Override - public void write(char[] cbuf, int off, int len) { - _buffer.append(cbuf, off, len); - } - - @Override - public void write(int c) { - _buffer.append((char) c); - } - - @Override - public void write(String str) { _buffer.append(str, 0, str.length()); } - - @Override - public void write(String str, int off, int len) { - _buffer.append(str, 0, str.length()); - } - - /* - ///////////////////////////////////////////////////////////// - // Extended API - ///////////////////////////////////////////////////////////// - */ - - /** - * Main access method that will construct a String that contains all the contents, release all internal buffers we - * may have, and return result String.Note that the method is not idempotent -- if called second time, will just - * return an empty String. - * - * @return Undocumented. - */ - public String getAndClear() - { - String result = _buffer.contentsAsString(); - _buffer.releaseBuffers(); - return result; - } -} diff --git a/src/org/codehaus/jackson/io/UTF32Reader.java b/src/org/codehaus/jackson/io/UTF32Reader.java deleted file mode 100644 index 4e7d83baec..0000000000 --- a/src/org/codehaus/jackson/io/UTF32Reader.java +++ /dev/null @@ -1,214 +0,0 @@ -package org.codehaus.jackson.io; - -import java.io.*; - - -/** - * Since JDK does not come with UTF-32/UCS-4, let's implement a simple - * decoder to use. - */ -public final class UTF32Reader - extends BaseReader -{ - final boolean mBigEndian; - - /** - * Although input is fine with full Unicode set, Java still uses - * 16-bit chars, so we may have to split high-order chars into - * surrogate pairs. - */ - char mSurrogate = NULL_CHAR; - - /** - * Total read character count; used for error reporting purposes - */ - int mCharCount = 0; - - /** - * Total read byte count; used for error reporting purposes - */ - int mByteCount = 0; - - /* - //////////////////////////////////////// - // Life-cycle - //////////////////////////////////////// - */ - - public UTF32Reader(IOContext ctxt, - InputStream in, byte[] buf, int ptr, int len, - boolean isBigEndian) - { - super(ctxt, in, buf, ptr, len); - mBigEndian = isBigEndian; - } - - /* - //////////////////////////////////////// - // Public API - //////////////////////////////////////// - */ - - @Override - public int read(char[] cbuf, int start, int len) - throws IOException - { - // Already EOF? - if (mBuffer == null) { - return -1; - } - if (len < 1) { - return len; - } - // Let's then ensure there's enough room... - if (start < 0 || (start+len) > cbuf.length) { - reportBounds(cbuf, start, len); - } - - len += start; - int outPtr = start; - - // Ok, first; do we have a surrogate from last round? - if (mSurrogate != NULL_CHAR) { - cbuf[outPtr++] = mSurrogate; - mSurrogate = NULL_CHAR; - // No need to load more, already got one char - } else { - /* Note: we'll try to avoid blocking as much as possible. As a - * result, we only need to get 4 bytes for a full char. - */ - int left = (mLength - mPtr); - if (left < 4) { - if (!loadMore(left)) { // (legal) EOF? - return -1; - } - } - } - - main_loop: - while (outPtr < len) { - int ptr = mPtr; - int ch; - - if (mBigEndian) { - ch = (mBuffer[ptr] << 24) | ((mBuffer[ptr+1] & 0xFF) << 16) - | ((mBuffer[ptr+2] & 0xFF) << 8) | (mBuffer[ptr+3] & 0xFF); - } else { - ch = (mBuffer[ptr] & 0xFF) | ((mBuffer[ptr+1] & 0xFF) << 8) - | ((mBuffer[ptr+2] & 0xFF) << 16) | (mBuffer[ptr+3] << 24); - } - mPtr += 4; - - // Does it need to be split to surrogates? - // (also, we can and need to verify illegal chars) - if (ch > 0xFFFF) { // need to split into surrogates? - if (ch > LAST_VALID_UNICODE_CHAR) { - reportInvalid(ch, outPtr-start, - "(above "+Integer.toHexString(LAST_VALID_UNICODE_CHAR)+") "); - } - ch -= 0x10000; // to normalize it starting with 0x0 - cbuf[outPtr++] = (char) (0xD800 + (ch >> 10)); - // hmmh. can this ever be 0? (not legal, at least?) - ch = (0xDC00 | (ch & 0x03FF)); - // Room for second part? - if (outPtr >= len) { // nope - mSurrogate = (char) ch; - break main_loop; - } - } - cbuf[outPtr++] = (char) ch; - if (mPtr >= mLength) { - break main_loop; - } - } - - len = outPtr - start; - mCharCount += len; - return len; - } - - /* - //////////////////////////////////////// - // Internal methods - //////////////////////////////////////// - */ - - private void reportUnexpectedEOF(int gotBytes, int needed) - throws IOException - { - int bytePos = mByteCount + gotBytes; - int charPos = mCharCount; - - throw new CharConversionException("Unexpected EOF in the middle of a 4-byte UTF-32 char: got " - +gotBytes+", needed "+needed - +", at char #"+charPos+", byte #"+bytePos+")"); - } - - private void reportInvalid(int value, int offset, String msg) - throws IOException - { - int bytePos = mByteCount + mPtr - 1; - int charPos = mCharCount + offset; - - throw new CharConversionException("Invalid UTF-32 character 0x" - +Integer.toHexString(value) - +msg+" at char #"+charPos+", byte #"+bytePos+")"); - } - - /** - * @param available Number of "unused" bytes in the input buffer - * - * @return True, if enough bytes were read to allow decoding of at least - * one full character; false if EOF was encountered instead. - */ - private boolean loadMore(int available) - throws IOException - { - mByteCount += (mLength - available); - - // Bytes that need to be moved to the beginning of buffer? - if (available > 0) { - if (mPtr > 0) { - for (int i = 0; i < available; ++i) { - mBuffer[i] = mBuffer[mPtr+i]; - } - mPtr = 0; - } - mLength = available; - } else { - /* Ok; here we can actually reasonably expect an EOF, - * so let's do a separate read right away: - */ - mPtr = 0; - int count = mIn.read(mBuffer); - if (count < 1) { - mLength = 0; - if (count < 0) { // -1 - freeBuffers(); // to help GC? - return false; - } - // 0 count is no good; let's err out - reportStrangeStream(); - } - mLength = count; - } - - /* Need at least 4 bytes; if we don't get that many, it's an - * error. - */ - while (mLength < 4) { - int count = mIn.read(mBuffer, mLength, mBuffer.length - mLength); - if (count < 1) { - if (count < 0) { // -1, EOF... no good! - freeBuffers(); // to help GC? - reportUnexpectedEOF(mLength, 4); - } - // 0 count is no good; let's err out - reportStrangeStream(); - } - mLength += count; - } - return true; - } -} - diff --git a/src/org/codehaus/jackson/io/UTF8Writer.java b/src/org/codehaus/jackson/io/UTF8Writer.java deleted file mode 100644 index c874f1ad9c..0000000000 --- a/src/org/codehaus/jackson/io/UTF8Writer.java +++ /dev/null @@ -1,385 +0,0 @@ -package org.codehaus.jackson.io; - -import java.io.*; - - -public final class UTF8Writer - extends Writer -{ - final static int SURR1_FIRST = 0xD800; - final static int SURR1_LAST = 0xDBFF; - final static int SURR2_FIRST = 0xDC00; - final static int SURR2_LAST = 0xDFFF; - - final protected IOContext mContext; - - OutputStream mOut; - - byte[] mOutBuffer; - - final int mOutBufferLast; - - int mOutPtr; - - /** - * When outputting chars from BMP, surrogate pairs need to be coalesced. - * To do this, both pairs must be known first; and since it is possible - * pairs may be split, we need temporary storage for the first half - */ - int mSurrogate = 0; - - public UTF8Writer(IOContext ctxt, OutputStream out) - { - mContext = ctxt; - mOut = out; - - mOutBuffer = ctxt.allocWriteEncodingBuffer(); - /* Max. expansion for a single char (in unmodified UTF-8) is - * 4 bytes (or 3 depending on how you view it -- 4 when recombining - * surrogate pairs) - */ - mOutBufferLast = mOutBuffer.length - 4; - mOutPtr = 0; - } - - @Override - public Writer append(char c) - throws IOException - { - write(c); - return this; - } - - @Override - public void close() - throws IOException - { - if (mOut != null) { - if (mOutPtr > 0) { - mOut.write(mOutBuffer, 0, mOutPtr); - mOutPtr = 0; - } - OutputStream out = mOut; - mOut = null; - - byte[] buf = mOutBuffer; - if (buf != null) { - mOutBuffer = null; - mContext.releaseWriteEncodingBuffer(buf); - } - - out.close(); - - /* Let's 'flush' orphan surrogate, no matter what; but only - * after cleanly closing everything else. - */ - int code = mSurrogate; - mSurrogate = 0; - if (code > 0) { - throwIllegal(code); - } - } - } - - @Override - public void flush() - throws IOException - { - if (mOutPtr > 0) { - mOut.write(mOutBuffer, 0, mOutPtr); - mOutPtr = 0; - } - mOut.flush(); - } - - @Override - public void write(char[] cbuf) - throws IOException - { - write(cbuf, 0, cbuf.length); - } - - @Override - public void write(char[] cbuf, int off, int len) - throws IOException - { - if (len < 2) { - if (len == 1) { - write(cbuf[off]); - } - return; - } - - // First: do we have a leftover surrogate to deal with? - if (mSurrogate > 0) { - char second = cbuf[off++]; - --len; - write(convertSurrogate(second)); - // will have at least one more char - } - - int outPtr = mOutPtr; - byte[] outBuf = mOutBuffer; - int outBufLast = mOutBufferLast; // has 4 'spare' bytes - - // All right; can just loop it nice and easy now: - len += off; // len will now be the end of input buffer - - output_loop: - for (; off < len; ) { - /* First, let's ensure we can output at least 4 bytes - * (longest UTF-8 encoded codepoint): - */ - if (outPtr >= outBufLast) { - mOut.write(outBuf, 0, outPtr); - outPtr = 0; - } - - int c = cbuf[off++]; - // And then see if we have an Ascii char: - if (c < 0x80) { // If so, can do a tight inner loop: - outBuf[outPtr++] = (byte)c; - // Let's calc how many ascii chars we can copy at most: - int maxInCount = (len - off); - int maxOutCount = (outBufLast - outPtr); - - if (maxInCount > maxOutCount) { - maxInCount = maxOutCount; - } - maxInCount += off; - ascii_loop: - while (true) { - if (off >= maxInCount) { // done with max. ascii seq - continue output_loop; - } - c = cbuf[off++]; - if (c >= 0x80) { - break ascii_loop; - } - outBuf[outPtr++] = (byte) c; - } - } - - // Nope, multi-byte: - if (c < 0x800) { // 2-byte - outBuf[outPtr++] = (byte) (0xc0 | (c >> 6)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - } else { // 3 or 4 bytes - // Surrogates? - if (c < SURR1_FIRST || c > SURR2_LAST) { - outBuf[outPtr++] = (byte) (0xe0 | (c >> 12)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - continue; - } - // Yup, a surrogate: - if (c > SURR1_LAST) { // must be from first range - mOutPtr = outPtr; - throwIllegal(c); - } - mSurrogate = c; - // and if so, followed by another from next range - if (off >= len) { // unless we hit the end? - break; - } - c = convertSurrogate(cbuf[off++]); - if (c > 0x10FFFF) { // illegal in JSON as well as in XML - mOutPtr = outPtr; - throwIllegal(c); - } - outBuf[outPtr++] = (byte) (0xf0 | (c >> 18)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 12) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - } - } - mOutPtr = outPtr; - } - - @Override - public void write(int c) throws IOException - { - // First; do we have a left over surrogate? - if (mSurrogate > 0) { - c = convertSurrogate(c); - // If not, do we start with a surrogate? - } else if (c >= SURR1_FIRST && c <= SURR2_LAST) { - // Illegal to get second part without first: - if (c > SURR1_LAST) { - throwIllegal(c); - } - // First part just needs to be held for now - mSurrogate = c; - return; - } - - if (mOutPtr >= mOutBufferLast) { // let's require enough room, first - mOut.write(mOutBuffer, 0, mOutPtr); - mOutPtr = 0; - } - - if (c < 0x80) { // ascii - mOutBuffer[mOutPtr++] = (byte) c; - } else { - int ptr = mOutPtr; - if (c < 0x800) { // 2-byte - mOutBuffer[ptr++] = (byte) (0xc0 | (c >> 6)); - mOutBuffer[ptr++] = (byte) (0x80 | (c & 0x3f)); - } else if (c <= 0xFFFF) { // 3 bytes - mOutBuffer[ptr++] = (byte) (0xe0 | (c >> 12)); - mOutBuffer[ptr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - mOutBuffer[ptr++] = (byte) (0x80 | (c & 0x3f)); - } else { // 4 bytes - if (c > 0x10FFFF) { // illegal - throwIllegal(c); - } - mOutBuffer[ptr++] = (byte) (0xf0 | (c >> 18)); - mOutBuffer[ptr++] = (byte) (0x80 | ((c >> 12) & 0x3f)); - mOutBuffer[ptr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - mOutBuffer[ptr++] = (byte) (0x80 | (c & 0x3f)); - } - mOutPtr = ptr; - } - } - - @Override - public void write(String str) throws IOException - { - write(str, 0, str.length()); - } - - @Override - public void write(String str, int off, int len) throws IOException - { - if (len < 2) { - if (len == 1) { - write(str.charAt(off)); - } - return; - } - - // First: do we have a leftover surrogate to deal with? - if (mSurrogate > 0) { - char second = str.charAt(off++); - --len; - write(convertSurrogate(second)); - // will have at least one more char (case of 1 char was checked earlier on) - } - - int outPtr = mOutPtr; - byte[] outBuf = mOutBuffer; - int outBufLast = mOutBufferLast; // has 4 'spare' bytes - - // All right; can just loop it nice and easy now: - len += off; // len will now be the end of input buffer - - output_loop: - for (; off < len; ) { - /* First, let's ensure we can output at least 4 bytes - * (longest UTF-8 encoded codepoint): - */ - if (outPtr >= outBufLast) { - mOut.write(outBuf, 0, outPtr); - outPtr = 0; - } - - int c = str.charAt(off++); - // And then see if we have an Ascii char: - if (c < 0x80) { // If so, can do a tight inner loop: - outBuf[outPtr++] = (byte)c; - // Let's calc how many ascii chars we can copy at most: - int maxInCount = (len - off); - int maxOutCount = (outBufLast - outPtr); - - if (maxInCount > maxOutCount) { - maxInCount = maxOutCount; - } - maxInCount += off; - ascii_loop: - while (true) { - if (off >= maxInCount) { // done with max. ascii seq - continue output_loop; - } - c = str.charAt(off++); - if (c >= 0x80) { - break ascii_loop; - } - outBuf[outPtr++] = (byte) c; - } - } - - // Nope, multi-byte: - if (c < 0x800) { // 2-byte - outBuf[outPtr++] = (byte) (0xc0 | (c >> 6)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - } else { // 3 or 4 bytes - // Surrogates? - if (c < SURR1_FIRST || c > SURR2_LAST) { - outBuf[outPtr++] = (byte) (0xe0 | (c >> 12)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - continue; - } - // Yup, a surrogate: - if (c > SURR1_LAST) { // must be from first range - mOutPtr = outPtr; - throwIllegal(c); - } - mSurrogate = c; - // and if so, followed by another from next range - if (off >= len) { // unless we hit the end? - break; - } - c = convertSurrogate(str.charAt(off++)); - if (c > 0x10FFFF) { // illegal, as per RFC 4627 - mOutPtr = outPtr; - throwIllegal(c); - } - outBuf[outPtr++] = (byte) (0xf0 | (c >> 18)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 12) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - outBuf[outPtr++] = (byte) (0x80 | (c & 0x3f)); - } - } - mOutPtr = outPtr; - } - - /* - //////////////////////////////////////////////////////////// - // Internal methods - //////////////////////////////////////////////////////////// - */ - - /** - * Method called to calculate UTF codepoint, from a surrogate pair. - */ - private int convertSurrogate(int secondPart) - throws IOException - { - int firstPart = mSurrogate; - mSurrogate = 0; - - // Ok, then, is the second part valid? - if (secondPart < SURR2_FIRST || secondPart > SURR2_LAST) { - throw new IOException("Broken surrogate pair: first char 0x"+Integer.toHexString(firstPart)+", second 0x"+Integer.toHexString(secondPart)+"; illegal combination"); - } - return 0x10000 + ((firstPart - SURR1_FIRST) << 10) + (secondPart - SURR2_FIRST); - } - - private void throwIllegal(int code) - throws IOException - { - if (code > 0x10FFFF) { // over max? - throw new IOException("Illegal character point (0x"+Integer.toHexString(code)+") to output; max is 0x10FFFF as per RFC 4627"); - } - if (code >= SURR1_FIRST) { - if (code <= SURR1_LAST) { // Unmatched first part (closing without second part?) - throw new IOException("Unmatched first part of surrogate pair (0x"+Integer.toHexString(code)+")"); - } - throw new IOException("Unmatched second part of surrogate pair (0x"+Integer.toHexString(code)+")"); - } - - // should we ever get this? - throw new IOException("Illegal character point (0x"+Integer.toHexString(code)+") to output"); - } -} diff --git a/src/org/codehaus/jackson/sym/BytesToNameCanonicalizer.java b/src/org/codehaus/jackson/sym/BytesToNameCanonicalizer.java deleted file mode 100644 index 0aff7174b9..0000000000 --- a/src/org/codehaus/jackson/sym/BytesToNameCanonicalizer.java +++ /dev/null @@ -1,961 +0,0 @@ -package org.codehaus.jackson.sym; - -import java.util.Arrays; - -import org.codehaus.jackson.util.InternCache; - -/** - * This class is basically a caching symbol table implementation used for - * canonicalizing {@link Name}s, constructed directly from a byte-based - * input source. - * - * @author Tatu Saloranta - */ -public final class BytesToNameCanonicalizer -{ - protected static final int DEFAULT_TABLE_SIZE = 64; - - /** - * Let's not expand symbol tables past some maximum size; - * this should protected against OOMEs caused by large documents - * with uniquer (~= random) names. - * - * @since 1.5 - */ - protected static final int MAX_TABLE_SIZE = 0x10000; // 64k entries == 256k mem - - /** - * Let's only share reasonably sized symbol tables. Max size set to 3/4 of 16k; - * this corresponds to 64k main hash index. This should allow for enough distinct - * names for almost any case. - */ - final static int MAX_ENTRIES_FOR_REUSE = 6000; - - final static int MIN_HASH_SIZE = 16; - - final static int INITIAL_COLLISION_LEN = 32; - - /** - * Bucket index is 8 bits, and value 0 is reserved to represent - * 'empty' status. - */ - final static int LAST_VALID_BUCKET = 0xFE; - - /* - /**************************************************** - /* Linkage, needed for merging symbol tables - /**************************************************** - */ - - final BytesToNameCanonicalizer _parent; - - /* - /**************************************************** - /* Main table state - /**************************************************** - */ - - /** - * Whether canonial symbol Strings are to be intern()ed before added - * to the table or not - */ - final boolean _intern; - - // // // First, global information - - /** - * Total number of Names in the symbol table - */ - private int _count; - - // // // Then information regarding primary hash array and its - // // // matching Name array - - /** - * Mask used to truncate 32-bit hash value to current hash array - * size; essentially, hash array size - 1 (since hash array sizes - * are 2^N). - */ - private int _mainHashMask; - - /** - * Array of 2^N size, which contains combination - * of 24-bits of hash (0 to indicate 'empty' slot), - * and 8-bit collision bucket index (0 to indicate empty - * collision bucket chain; otherwise subtract one from index) - */ - private int[] _mainHash; - - /** - * Array that contains Name instances matching - * entries in _mainHash. Contains nulls for unused - * entries. - */ - private Name[] _mainNames; - - // // // Then the collision/spill-over area info - - /** - * Array of heads of collision bucket chains; size dynamically - */ - private Bucket[] _collList; - - /** - * Total number of Names in collision buckets (included in - * _count along with primary entries) - */ - private int _collCount; - - /** - * Index of the first unused collision bucket entry (== size of - * the used portion of collision list): less than - * or equal to 0xFF (255), since max number of entries is 255 - * (8-bit, minus 0 used as 'empty' marker) - */ - private int _collEnd; - - // // // Info regarding pending rehashing... - - /** - * This flag is set if, after adding a new entry, it is deemed - * that a rehash is warranted if any more entries are to be added. - */ - private transient boolean _needRehash; - - /* - /**************************************************** - /* Sharing, versioning - /**************************************************** - */ - - // // // Which of the buffers may be shared (and are copy-on-write)? - - /** - * Flag that indicates whether underlying data structures for - * the main hash area are shared or not. If they are, then they - * need to be handled in copy-on-write way, i.e. if they need - * to be modified, a copy needs to be made first; at this point - * it will not be shared any more, and can be modified. - *

- * This flag needs to be checked both when adding new main entries, - * and when adding new collision list queues (i.e. creating a new - * collision list head entry) - */ - private boolean _mainHashShared; - - private boolean _mainNamesShared; - - /** - * Flag that indicates whether underlying data structures for - * the collision list are shared or not. If they are, then they - * need to be handled in copy-on-write way, i.e. if they need - * to be modified, a copy needs to be made first; at this point - * it will not be shared any more, and can be modified. - *

- * This flag needs to be checked when adding new collision entries. - */ - private boolean _collListShared; - - /* - /**************************************************** - /* Construction, merging - /**************************************************** - */ - - public static BytesToNameCanonicalizer createRoot() - { - return new BytesToNameCanonicalizer(DEFAULT_TABLE_SIZE, true); - } - - /** - * @param canonicalize Whether to canonicalize the string. - * @param intern Whether canonical symbol Strings should be interned - * or not - * @return Undocumented. - */ - public synchronized BytesToNameCanonicalizer makeChild(boolean canonicalize, - boolean intern) - { - return new BytesToNameCanonicalizer(this, intern); - } - - /** - * Method called by the using code to indicate it is done - * with this instance. This lets instance merge accumulated - * changes into parent (if need be), safely and efficiently, - * and without calling code having to know about parent - * information - */ - public void release() - { - if (maybeDirty() && _parent != null) { - _parent.mergeChild(this); - /* Let's also mark this instance as dirty, so that just in - * case release was too early, there's no corruption - * of possibly shared data. - */ - markAsShared(); - } - } - - private BytesToNameCanonicalizer(int hashSize, boolean intern) - { - _parent = null; - _intern = intern; - /* Sanity check: let's now allow hash sizes below certain - * min. value - */ - if (hashSize < MIN_HASH_SIZE) { - hashSize = MIN_HASH_SIZE; - } else { - /* Also; size must be 2^N; otherwise hash algorithm won't - * work... so let's just pad it up, if so - */ - if ((hashSize & (hashSize - 1)) != 0) { // only true if it's 2^N - int curr = MIN_HASH_SIZE; - while (curr < hashSize) { - curr += curr; - } - hashSize = curr; - } - } - initTables(hashSize); - } - - /** - * Constructor used when creating a child instance - */ - private BytesToNameCanonicalizer(BytesToNameCanonicalizer parent, boolean intern) - { - _parent = parent; - _intern = intern; - - // First, let's copy the state as is: - _count = parent._count; - _mainHashMask = parent._mainHashMask; - _mainHash = parent._mainHash; - _mainNames = parent._mainNames; - _collList = parent._collList; - _collCount = parent._collCount; - _collEnd = parent._collEnd; - _needRehash = false; - // And consider all shared, so far: - _mainHashShared = true; - _mainNamesShared = true; - _collListShared = true; - } - - private void initTables(int hashSize) - { - _count = 0; - _mainHash = new int[hashSize]; - _mainNames = new Name[hashSize]; - _mainHashShared = false; - _mainNamesShared = false; - _mainHashMask = hashSize - 1; - - _collListShared = true; // just since it'll need to be allocated - _collList = null; - _collEnd = 0; - - _needRehash = false; - } - - private synchronized void mergeChild(BytesToNameCanonicalizer child) - { - // Only makes sense if child has more entries - int childCount = child._count; - if (childCount <= _count) { - return; - } - - /* One caveat: let's try to avoid problems with - * degenerate cases of documents with generated "random" - * names: for these, symbol tables would bloat indefinitely. - * One way to do this is to just purge tables if they grow - * too large, and that's what we'll do here. - */ - if (child.size() > MAX_ENTRIES_FOR_REUSE) { - /* Should there be a way to get notified about this - * event, to log it or such? (as it's somewhat abnormal - * thing to happen) - */ - // At any rate, need to clean up the tables, then: - initTables(DEFAULT_TABLE_SIZE); - } else { - _count = child._count; - _mainHash = child._mainHash; - _mainNames = child._mainNames; - _mainHashShared = true; // shouldn't matter for parent - _mainNamesShared = true; // - "" - - _mainHashMask = child._mainHashMask; - _collList = child._collList; - _collCount = child._collCount; - _collEnd = child._collEnd; - } - } - - private void markAsShared() - { - _mainHashShared = true; - _mainNamesShared = true; - _collListShared = true; - } - - /* - /**************************************************** - /* API, accessors - /**************************************************** - */ - - public int size() { return _count; } - - /** - * Method called to check to quickly see if a child symbol table may have gotten additional entries. Used for - * checking to see if a child table should be merged into shared table. - * - * @return Undocumented. - */ - public boolean maybeDirty() - { - return !_mainHashShared; - } - - public static Name getEmptyName() - { - return Name1.getEmptyName(); - } - - /** - * Finds and returns name matching the specified symbol, if such - * name already exists in the table. - * If not, will return null. - *

- * Note: separate methods to optimize common case of - * short element/attribute names (4 or less ascii characters) - * - * @param firstQuad int32 containing first 4 bytes of the name; - * if the whole name less than 4 bytes, padded with zero bytes - * in front (zero MSBs, ie. right aligned) - * - * @return Name matching the symbol passed (or constructed for - * it) - */ - public Name findName(int firstQuad) - { - int hash = calcHash(firstQuad); - int ix = (hash & _mainHashMask); - int val = _mainHash[ix]; - - /* High 24 bits of the value are low 24 bits of hash (low 8 bits - * are bucket index)... match? - */ - if ((((val >> 8) ^ hash) << 8) == 0) { // match - // Ok, but do we have an actual match? - Name name = _mainNames[ix]; - if (name == null) { // main slot empty; can't find - return null; - } - if (name.equals(firstQuad)) { - return name; - } - } else if (val == 0) { // empty slot? no match - return null; - } - // Maybe a spill-over? - val &= 0xFF; - if (val > 0) { // 0 means 'empty' - val -= 1; // to convert from 1-based to 0... - Bucket bucket = _collList[val]; - if (bucket != null) { - return bucket.find(hash, firstQuad, 0); - } - } - // Nope, no match whatsoever - return null; - } - - /** - * Finds and returns name matching the specified symbol, if such - * name already exists in the table. - * If not, will return null. - *

- * Note: separate methods to optimize common case of relatively - * short element/attribute names (8 or less ascii characters) - * - * @param firstQuad int32 containing first 4 bytes of the name. - * @param secondQuad int32 containing bytes 5 through 8 of the - * name; if less than 8 bytes, padded with up to 3 zero bytes - * in front (zero MSBs, ie. right aligned) - * - * @return Name matching the symbol passed (or constructed for - * it) - */ - public Name findName(int firstQuad, int secondQuad) - { - int hash = calcHash(firstQuad, secondQuad); - int ix = (hash & _mainHashMask); - int val = _mainHash[ix]; - - /* High 24 bits of the value are low 24 bits of hash (low 8 bits - * are bucket index)... match? - */ - if ((((val >> 8) ^ hash) << 8) == 0) { // match - // Ok, but do we have an actual match? - Name name = _mainNames[ix]; - if (name == null) { // main slot empty; can't find - return null; - } - if (name.equals(firstQuad, secondQuad)) { - return name; - } - } else if (val == 0) { // empty slot? no match - return null; - } - // Maybe a spill-over? - val &= 0xFF; - if (val > 0) { // 0 means 'empty' - val -= 1; // to convert from 1-based to 0... - Bucket bucket = _collList[val]; - if (bucket != null) { - return bucket.find(hash, firstQuad, secondQuad); - } - } - // Nope, no match whatsoever - return null; - } - - /** - * Finds and returns name matching the specified symbol, if such - * name already exists in the table; or if not, creates name object, - * adds to the table, and returns it. - *

- * Note: this is the general purpose method that can be called for - * names of any length. However, if name is less than 9 bytes long, - * it is preferable to call the version optimized for short - * names. - * - * @param quads Array of int32s, each of which contain 4 bytes of - * encoded name - * @param qlen Number of int32s, starting from index 0, in quads - * parameter - * - * @return Name matching the symbol passed (or constructed for - * it) - */ - public Name findName(int[] quads, int qlen) - { - /* // Not needed, never gets called - if (qlen < 3) { // another sanity check - return findName(quads[0], (qlen < 2) ? 0 : quads[1]); - } - */ - int hash = calcHash(quads, qlen); - // (for rest of comments regarding logic, see method above) - int ix = (hash & _mainHashMask); - int val = _mainHash[ix]; - if ((((val >> 8) ^ hash) << 8) == 0) { - Name name = _mainNames[ix]; - if (name == null // main slot empty; no collision list then either - || name.equals(quads, qlen)) { // should be match, let's verify - return name; - } - } else if (val == 0) { // empty slot? no match - return null; - } - val &= 0xFF; - if (val > 0) { // 0 means 'empty' - val -= 1; // to convert from 1-based to 0... - Bucket bucket = _collList[val]; - if (bucket != null) { - return bucket.find(hash, quads, qlen); - } - } - return null; - } - - /* - /**************************************** - /* API, mutators - /**************************************** - */ - - public Name addName(String symbolStr, int[] quads, int qlen) - { - if (_intern) { - symbolStr = InternCache.instance.intern(symbolStr); - } - int hash = calcHash(quads, qlen); - Name symbol = constructName(hash, symbolStr, quads, qlen); - _addSymbol(hash, symbol); - return symbol; - } - - /* - /**************************************** - /* Helper methods - /**************************************** - */ - - public final static int calcHash(int firstQuad) - { - int hash = firstQuad; - hash ^= (hash >>> 16); // to xor hi- and low- 16-bits - hash ^= (hash >>> 8); // as well as lowest 2 bytes - return hash; - } - - public final static int calcHash(int firstQuad, int secondQuad) - { - int hash = (firstQuad * 31) + secondQuad; - - // If this was called for single-quad instance: - //int hash = (secondQuad == 0) ? firstQuad : ((firstQuad * 31) + secondQuad); - - hash ^= (hash >>> 16); // to xor hi- and low- 16-bits - hash ^= (hash >>> 8); // as well as lowest 2 bytes - return hash; - } - - public final static int calcHash(int[] quads, int qlen) - { - // Note: may be called for qlen < 3 - int hash = quads[0]; - for (int i = 1; i < qlen; ++i) { - hash = (hash * 31) + quads[i]; - } - - hash ^= (hash >>> 16); // to xor hi- and low- 16-bits - hash ^= (hash >>> 8); // as well as lowest 2 bytes - - return hash; - } - - /* 26-Nov-2008, tatu: not used currently; if not used in near future, - * let's just delete it. - */ - /* - public static int[] calcQuads(byte[] wordBytes) - { - int blen = wordBytes.length; - int[] result = new int[(blen + 3) / 4]; - for (int i = 0; i < blen; ++i) { - int x = wordBytes[i] & 0xFF; - - if (++i < blen) { - x = (x << 8) | (wordBytes[i] & 0xFF); - if (++i < blen) { - x = (x << 8) | (wordBytes[i] & 0xFF); - if (++i < blen) { - x = (x << 8) | (wordBytes[i] & 0xFF); - } - } - } - result[i >> 2] = x; - } - return result; - } - */ - - /* - /**************************************** - /* Standard methods - /**************************************** - */ - - /* - @Override - public String toString() - { - StringBuilder sb = new StringBuilder(); - sb.append("[BytesToNameCanonicalizer, size: "); - sb.append(_count); - sb.append('/'); - sb.append(_mainHash.length); - sb.append(", "); - sb.append(_collCount); - sb.append(" coll; avg length: "); - - // Average length: minimum of 1 for all (1 == primary hit); - // and then 1 per each traversal for collisions/buckets - //int maxDist = 1; - int pathCount = _count; - for (int i = 0; i < _collEnd; ++i) { - int spillLen = _collList[i].length(); - for (int j = 1; j <= spillLen; ++j) { - pathCount += j; - } - } - double avgLength; - - if (_count == 0) { - avgLength = 0.0; - } else { - avgLength = (double) pathCount / (double) _count; - } - // let's round up a bit (two 2 decimal places) - //avgLength -= (avgLength % 0.01); - - sb.append(avgLength); - sb.append(']'); - return sb.toString(); - } - */ - - /* - /**************************************** - /* Internal methods - /**************************************** - */ - - private void _addSymbol(int hash, Name symbol) - { - if (_mainHashShared) { // always have to modify main entry - unshareMain(); - } - // First, do we need to rehash? - if (_needRehash) { - rehash(); - } - - ++_count; - - /* Ok, enough about set up: now we need to find the slot to add - * symbol in: - */ - int ix = (hash & _mainHashMask); - if (_mainNames[ix] == null) { // primary empty? - _mainHash[ix] = (hash << 8); - if (_mainNamesShared) { - unshareNames(); - } - _mainNames[ix] = symbol; - } else { // nope, it's a collision, need to spill over - /* How about spill-over area... do we already know the bucket - * (is the case if it's not the first collision) - */ - if (_collListShared) { - unshareCollision(); // also allocates if list was null - } - - ++_collCount; - int entryValue = _mainHash[ix]; - int bucket = entryValue & 0xFF; - if (bucket == 0) { // first spill over? - if (_collEnd <= LAST_VALID_BUCKET) { // yup, still unshared bucket - bucket = _collEnd; - ++_collEnd; - // need to expand? - if (bucket >= _collList.length) { - expandCollision(); - } - } else { // nope, have to share... let's find shortest? - bucket = findBestBucket(); - } - // Need to mark the entry... and the spill index is 1-based - _mainHash[ix] = (entryValue & ~0xFF) | (bucket + 1); - } else { - --bucket; // 1-based index in value - } - - // And then just need to link the new bucket entry in - _collList[bucket] = new Bucket(symbol, _collList[bucket]); - } - - /* Ok. Now, do we need a rehash next time? Need to have at least - * 50% fill rate no matter what: - */ - { - int hashSize = _mainHash.length; - if (_count > (hashSize >> 1)) { - int hashQuarter = (hashSize >> 2); - /* And either strictly above 75% (the usual) or - * just 50%, and collision count >= 25% of total hash size - */ - if (_count > (hashSize - hashQuarter)) { - _needRehash = true; - } else if (_collCount >= hashQuarter) { - _needRehash = true; - } - } - } - } - - private void rehash() - { - _needRehash = false; - // Note: since we'll make copies, no need to unshare, can just mark as such: - _mainNamesShared = false; - - /* And then we can first deal with the main hash area. Since we - * are expanding linearly (double up), we know there'll be no - * collisions during this phase. - */ - int[] oldMainHash = _mainHash; - int len = oldMainHash.length; - int newLen = len+len; - - /* 13-Mar-2010, tatu: Let's guard against OOME that could be caused by - * large documents with unique (or mostly so) names - */ - if (newLen > MAX_TABLE_SIZE) { - nukeSymbols(); - return; - } - - _mainHash = new int[newLen]; - _mainHashMask = (newLen - 1); - Name[] oldNames = _mainNames; - _mainNames = new Name[newLen]; - int symbolsSeen = 0; // let's do a sanity check - for (int i = 0; i < len; ++i) { - Name symbol = oldNames[i]; - if (symbol != null) { - ++symbolsSeen; - int hash = symbol.hashCode(); - int ix = (hash & _mainHashMask); - _mainNames[ix] = symbol; - _mainHash[ix] = hash << 8; // will clear spill index - } - } - - /* And then the spill area. This may cause collisions, although - * not necessarily as many as there were earlier. Let's allocate - * same amount of space, however - */ - int oldEnd = _collEnd; - if (oldEnd == 0) { // no prior collisions... - return; - } - - _collCount = 0; - _collEnd = 0; - _collListShared = false; - - Bucket[] oldBuckets = _collList; - _collList = new Bucket[oldBuckets.length]; - for (int i = 0; i < oldEnd; ++i) { - for (Bucket curr = oldBuckets[i]; curr != null; curr = curr.mNext) { - ++symbolsSeen; - Name symbol = curr.mName; - int hash = symbol.hashCode(); - int ix = (hash & _mainHashMask); - int val = _mainHash[ix]; - if (_mainNames[ix] == null) { // no primary entry? - _mainHash[ix] = (hash << 8); - _mainNames[ix] = symbol; - } else { // nope, it's a collision, need to spill over - ++_collCount; - int bucket = val & 0xFF; - if (bucket == 0) { // first spill over? - if (_collEnd <= LAST_VALID_BUCKET) { // yup, still unshared bucket - bucket = _collEnd; - ++_collEnd; - // need to expand? - if (bucket >= _collList.length) { - expandCollision(); - } - } else { // nope, have to share... let's find shortest? - bucket = findBestBucket(); - } - // Need to mark the entry... and the spill index is 1-based - _mainHash[ix] = (val & ~0xFF) | (bucket + 1); - } else { - --bucket; // 1-based index in value - } - // And then just need to link the new bucket entry in - _collList[bucket] = new Bucket(symbol, _collList[bucket]); - } - } // for (... buckets in the chain ...) - } // for (... list of bucket heads ... ) - - if (symbolsSeen != _count) { // sanity check - throw new RuntimeException("Internal error: count after rehash "+symbolsSeen+"; should be "+_count); - } - } - - /** - * Helper method called to empty all shared symbols, but to leave - * arrays allocated - */ - private void nukeSymbols() - { - _count = 0; - Arrays.fill(_mainHash, 0); - Arrays.fill(_mainNames, null); - Arrays.fill(_collList, null); - _collCount = 0; - _collEnd = 0; - } - - /** - * Method called to find the best bucket to spill a Name over to: - * usually the first bucket that has only one entry, but in general - * first one of the buckets with least number of entries - */ - private int findBestBucket() - { - Bucket[] buckets = _collList; - int bestCount = Integer.MAX_VALUE; - int bestIx = -1; - - for (int i = 0, len = _collEnd; i < len; ++i) { - int count = buckets[i].length(); - if (count < bestCount) { - if (count == 1) { // best possible - return i; - } - bestCount = count; - bestIx = i; - } - } - return bestIx; - } - - /** - * Method that needs to be called, if the main hash structure - * is (may be) shared. This happens every time something is added, - * even if addition is to the collision list (since collision list - * index comes from lowest 8 bits of the primary hash entry) - */ - private void unshareMain() - { - int[] old = _mainHash; - int len = _mainHash.length; - - _mainHash = new int[len]; - System.arraycopy(old, 0, _mainHash, 0, len); - _mainHashShared = false; - } - - private void unshareCollision() - { - Bucket[] old = _collList; - if (old == null) { - _collList = new Bucket[INITIAL_COLLISION_LEN]; - } else { - int len = old.length; - _collList = new Bucket[len]; - System.arraycopy(old, 0, _collList, 0, len); - } - _collListShared = false; - } - - private void unshareNames() - { - Name[] old = _mainNames; - int len = old.length; - _mainNames = new Name[len]; - System.arraycopy(old, 0, _mainNames, 0, len); - _mainNamesShared = false; - } - - private void expandCollision() - { - Bucket[] old = _collList; - int len = old.length; - _collList = new Bucket[len+len]; - System.arraycopy(old, 0, _collList, 0, len); - } - - - /* - /**************************************** - /* Constructing name objects - /**************************************** - */ - - /* - private static Name constructName(int hash, String name, int q1, int q2) - { - if (q2 == 0) { // one quad only? - return new Name1(name, hash, q1); - } - return new Name2(name, hash, q1, q2); - } - */ - - private static Name constructName(int hash, String name, int[] quads, int qlen) - { - if (qlen < 4) { // Need to check for 3 quad one, can do others too - switch (qlen) { - case 1: - return new Name1(name, hash, quads[0]); - case 2: - return new Name2(name, hash, quads[0], quads[1]); - case 3: - return new Name3(name, hash, quads[0], quads[1], quads[2]); - default: - } - } - // Otherwise, need to copy the incoming buffer - int[] buf = new int[qlen]; - for (int i = 0; i < qlen; ++i) { - buf[i] = quads[i]; - } - return new NameN(name, hash, buf, qlen); - } - - /* - /**************************************** - /* Helper classes - /**************************************** - */ - - final static class Bucket - { - final Name mName; - final Bucket mNext; - - Bucket(Name name, Bucket next) - { - mName = name; - mNext = next; - } - - public int length() - { - int len = 1; - for (Bucket curr = mNext; curr != null; curr = curr.mNext) { - ++len; - } - return len; - } - - public Name find(int hash, int firstQuad, int secondQuad) - { - if (mName.hashCode() == hash) { - if (mName.equals(firstQuad, secondQuad)) { - return mName; - } - } - for (Bucket curr = mNext; curr != null; curr = curr.mNext) { - Name currName = curr.mName; - if (currName.hashCode() == hash) { - if (currName.equals(firstQuad, secondQuad)) { - return currName; - } - } - } - return null; - } - - public Name find(int hash, int[] quads, int qlen) - { - if (mName.hashCode() == hash) { - if (mName.equals(quads, qlen)) { - return mName; - } - } - for (Bucket curr = mNext; curr != null; curr = curr.mNext) { - Name currName = curr.mName; - if (currName.hashCode() == hash) { - if (currName.equals(quads, qlen)) { - return currName; - } - } - } - return null; - } - } -} diff --git a/src/org/codehaus/jackson/sym/CharsToNameCanonicalizer.java b/src/org/codehaus/jackson/sym/CharsToNameCanonicalizer.java deleted file mode 100644 index b830a8d8ef..0000000000 --- a/src/org/codehaus/jackson/sym/CharsToNameCanonicalizer.java +++ /dev/null @@ -1,579 +0,0 @@ -package org.codehaus.jackson.sym; - -import java.util.Arrays; - -import org.codehaus.jackson.util.InternCache; - -/** - * This class is a kind of specialized type-safe Map, from char array to - * String value. Specialization means that in addition to type-safety - * and specific access patterns (key char array, Value optionally interned - * String; values added on access if necessary), and that instances are - * meant to be used concurrently, but by using well-defined mechanisms - * to obtain such concurrently usable instances. Main use for the class - * is to store symbol table information for things like compilers and - * parsers; especially when number of symbols (keywords) is limited. - *

- * For optimal performance, usage pattern should be one where matches - * should be very common (esp. after "warm-up"), and as with most hash-based - * maps/sets, that hash codes are uniformly distributed. Also, collisions - * are slightly more expensive than with HashMap or HashSet, since hash codes - * are not used in resolving collisions; that is, equals() comparison is - * done with all symbols in same bucket index.
- * Finally, rehashing is also more expensive, as hash codes are not - * stored; rehashing requires all entries' hash codes to be recalculated. - * Reason for not storing hash codes is reduced memory usage, hoping - * for better memory locality. - *

- * Usual usage pattern is to create a single "master" instance, and either - * use that instance in sequential fashion, or to create derived "child" - * instances, which after use, are asked to return possible symbol additions - * to master instance. In either case benefit is that symbol table gets - * initialized so that further uses are more efficient, as eventually all - * symbols needed will already be in symbol table. At that point no more - * Symbol String allocations are needed, nor changes to symbol table itself. - *

- * Note that while individual SymbolTable instances are NOT thread-safe - * (much like generic collection classes), concurrently used "child" - * instances can be freely used without synchronization. However, using - * master table concurrently with child instances can only be done if - * access to master instance is read-only (ie. no modifications done). - */ - -public final class CharsToNameCanonicalizer -{ - /** - * Default initial table size. Shouldn't be miniscule (as there's - * cost to both array realloc and rehashing), but let's keep - * it reasonably small nonetheless. For systems that properly - * reuse factories it doesn't matter either way; but when - * recreating factories often, initial overhead may dominate. - */ - protected static final int DEFAULT_TABLE_SIZE = 64; - - /** - * Let's not expand symbol tables past some maximum size; - * this should protected against OOMEs caused by large documents - * with uniquer (~= random) names. - * - * @since 1.5 - */ - protected static final int MAX_TABLE_SIZE = 0x10000; // 64k entries == 256k mem - - /** - * Let's only share reasonably sized symbol tables. Max size set to 3/4 of 16k; - * this corresponds to 64k main hash index. This should allow for enough distinct - * names for almost any case. - */ - final static int MAX_ENTRIES_FOR_REUSE = 12000; - - final static CharsToNameCanonicalizer sBootstrapSymbolTable; - static { - sBootstrapSymbolTable = new CharsToNameCanonicalizer(); - } - - /* - /**************************************** - /* Configuration: - /**************************************** - */ - - /** - * Sharing of learnt symbols is done by optional linking of symbol - * table instances with their parents. When parent linkage is - * defined, and child instance is released (call to release), - * parent's shared tables may be updated from the child instance. - */ - protected CharsToNameCanonicalizer _parent; - - /** - * Whether canonical symbol Strings are to be intern()ed before added - * to the table or not - */ - final protected boolean _intern; - - /** - * Whether any canonicalization should be attempted (whether using - * intern or not) - */ - final protected boolean _canonicalize; - - /* - /**************************************** - /* Actual symbol table data: - /**************************************** - */ - - /** - * Primary matching symbols; it's expected most match occur from - * here. - */ - protected String[] _symbols; - - /** - * Overflow buckets; if primary doesn't match, lookup is done - * from here. - *

- * Note: Number of buckets is half of number of symbol entries, on - * assumption there's less need for buckets. - */ - protected Bucket[] _buckets; - - /** - * Current size (number of entries); needed to know if and when - * rehash. - */ - protected int _size; - - /** - * Limit that indicates maximum size this instance can hold before - * it needs to be expanded and rehashed. Calculated using fill - * factor passed in to constructor. - */ - protected int _sizeThreshold; - - /** - * Mask used to get index from hash values; equal to - * _buckets.length - 1, when _buckets.length is - * a power of two. - */ - protected int _indexMask; - - /* - /**************************************** - /* State regarding shared arrays - /**************************************** - */ - - /** - * Flag that indicates if any changes have been made to the data; - * used to both determine if bucket array needs to be copied when - * (first) change is made, and potentially if updated bucket list - * is to be resync'ed back to master instance. - */ - protected boolean _dirty; - - /* - /**************************************** - /* Life-cycle - /**************************************** - */ - - /** - * Method called to create root canonicalizer for a {@link org.codehaus.jackson.JsonFactory} instance.Root instance - * is never used directly; its main use is for storing and sharing underlying symbol arrays as needed. - * - * @return Undocumented. - */ - public static CharsToNameCanonicalizer createRoot() - { - return sBootstrapSymbolTable.makeOrphan(); - } - - /** - * Main method for constructing a master symbol table instance. - * - * @param initialSize Minimum initial size for bucket array; internally - * will always use a power of two equal to or bigger than this value. - */ - private CharsToNameCanonicalizer() - { - // these settings don't really matter for the bootstrap instance - _canonicalize = true; - _intern = true; - // And we'll also set flags so no copying of buckets is needed: - _dirty = true; - initTables(DEFAULT_TABLE_SIZE); - } - - private void initTables(int initialSize) - { - _symbols = new String[initialSize]; - _buckets = new Bucket[initialSize >> 1]; - // Mask is easy to calc for powers of two. - _indexMask = initialSize - 1; - _size = 0; - // Hard-coded fill factor is 75% - _sizeThreshold = (initialSize - (initialSize >> 2)); - } - - /** - * Internal constructor used when creating child instances. - */ - private CharsToNameCanonicalizer(CharsToNameCanonicalizer parent, - boolean canonicalize, boolean intern, - String[] symbols, Bucket[] buckets, int size) - { - _parent = parent; - _canonicalize = canonicalize; - _intern = intern; - - _symbols = symbols; - _buckets = buckets; - _size = size; - // Hard-coded fill factor, 75% - int arrayLen = (symbols.length); - _sizeThreshold = arrayLen - (arrayLen >> 2); - _indexMask = (arrayLen - 1); - - // Need to make copies of arrays, if/when adding new entries - _dirty = false; - } - - /** - * "Factory" method; will create a new child instance of this symbol table.It will be a copy-on-write instance, - * ie.it will only use read-only copy of parent's data, but when changes are needed, a copy will be created.

- * Note: while this method is synchronized, it is generally not safe to both use makeChild/mergeChild, AND to use - * instance actively. Instead, a separate 'root' instance should be used on which only makeChild/mergeChild are - * called, but instance itself is not used as a symbol table. - * - * @param canonicalize Undocumented. - * @param intern Undocumented. - * @return Undocumented. - */ - public synchronized CharsToNameCanonicalizer makeChild(boolean canonicalize, boolean intern) - { - return new CharsToNameCanonicalizer(this, canonicalize, intern, _symbols, _buckets, _size); - } - - private CharsToNameCanonicalizer makeOrphan() - { - return new CharsToNameCanonicalizer(null, true, true, _symbols, _buckets, _size); - } - - /** - * Method that allows contents of child table to potentially be - * "merged in" with contents of this symbol table. - *

- * Note that caller has to make sure symbol table passed in is - * really a child or sibling of this symbol table. - */ - private synchronized void mergeChild(CharsToNameCanonicalizer child) - { - /* One caveat: let's try to avoid problems with - * degenerate cases of documents with generated "random" - * names: for these, symbol tables would bloat indefinitely. - * One way to do this is to just purge tables if they grow - * too large, and that's what we'll do here. - */ - if (child.size() > MAX_ENTRIES_FOR_REUSE) { - /* Should there be a way to get notified about this - * event, to log it or such? (as it's somewhat abnormal - * thing to happen) - */ - // At any rate, need to clean up the tables, then: - initTables(DEFAULT_TABLE_SIZE); - } else { - /* Otherwise, we'll merge changed stuff in, if there are - * more entries (which may not be the case if one of siblings - * has added symbols first or such) - */ - if (child.size() <= size()) { // nothing to add - return; - } - // Okie dokie, let's get the data in! - _symbols = child._symbols; - _buckets = child._buckets; - _size = child._size; - _sizeThreshold = child._sizeThreshold; - _indexMask = child._indexMask; - } - /* Dirty flag... well, let's just clear it, to force copying just - * in case. Shouldn't really matter, for master tables. - * (which this is, given something is merged to it etc) - */ - _dirty = false; - } - - public void release() - { - // If nothing has been added, nothing to do - if (!maybeDirty()) { - return; - } - if (_parent != null) { - _parent.mergeChild(this); - /* Let's also mark this instance as dirty, so that just in - * case release was too early, there's no corruption - * of possibly shared data. - */ - _dirty = false; - } - } - - /* - /**************************************** - /* Public API, generic accessors: - /**************************************** - */ - - public int size() { return _size; } - - public boolean maybeDirty() { return _dirty; } - - /* - /**************************************** - /* Public API, accessing symbols: - /**************************************** - */ - - public String findSymbol(char[] buffer, int start, int len, int hash) - { - if (len < 1) { // empty Strings are simplest to handle up front - return ""; - } - if (!_canonicalize) { // [JACKSON-259] - return new String(buffer, start, len); - } - - hash &= _indexMask; - - String sym = _symbols[hash]; - - // Optimal case; checking existing primary symbol for hash index: - if (sym != null) { - // Let's inline primary String equality checking: - if (sym.length() == len) { - int i = 0; - do { - if (sym.charAt(i) != buffer[start+i]) { - break; - } - } while (++i < len); - // Optimal case; primary match found - if (i == len) { - return sym; - } - } - // How about collision bucket? - Bucket b = _buckets[hash >> 1]; - if (b != null) { - sym = b.find(buffer, start, len); - if (sym != null) { - return sym; - } - } - } - - if (!_dirty) { //need to do copy-on-write? - copyArrays(); - _dirty = true; - } else if (_size >= _sizeThreshold) { // Need to expand? - rehash(); - /* Need to recalc hash; rare occurence (index mask has been - * recalculated as part of rehash) - */ - hash = calcHash(buffer, start, len) & _indexMask; - } - ++_size; - - String newSymbol = new String(buffer, start, len); - if (_intern) { - newSymbol = InternCache.instance.intern(newSymbol); - } - // Ok; do we need to add primary entry, or a bucket? - if (_symbols[hash] == null) { - _symbols[hash] = newSymbol; - } else { - int bix = hash >> 1; - _buckets[bix] = new Bucket(newSymbol, _buckets[bix]); - } - - return newSymbol; - } - - /** - * Implementation of a hashing method for variable length Strings.Most of the time intention is that this - * calculation is done by caller during parsing, not here; however, sometimes it needs to be done for parsed - * "String" too. - * - * @param buffer Undocumented. - * @param start Undocumented. - * @param len Length of String; has to be at least 1 (caller guarantees this pre-condition) - * @return Undocumented. - */ - public static int calcHash(char[] buffer, int start, int len) { - int hash = (int) buffer[0]; - for (int i = 1; i < len; ++i) { - hash = (hash * 31) + (int) buffer[i]; - } - return hash; - } - - public static int calcHash(String key) { - int hash = (int) key.charAt(0); - for (int i = 1, len = key.length(); i < len; ++i) { - hash = (hash * 31) + (int) key.charAt(i); - - } - return hash; - } - - /* - /**************************************** - /* Internal methods - /**************************************** - */ - - /** - * Method called when copy-on-write is needed; generally when first - * change is made to a derived symbol table. - */ - private void copyArrays() { - String[] oldSyms = _symbols; - int size = oldSyms.length; - _symbols = new String[size]; - System.arraycopy(oldSyms, 0, _symbols, 0, size); - Bucket[] oldBuckets = _buckets; - size = oldBuckets.length; - _buckets = new Bucket[size]; - System.arraycopy(oldBuckets, 0, _buckets, 0, size); - } - - /** - * Method called when size (number of entries) of symbol table grows - * so big that load factor is exceeded. Since size has to remain - * power of two, arrays will then always be doubled. Main work - * is really redistributing old entries into new String/Bucket - * entries. - */ - private void rehash() - { - int size = _symbols.length; - int newSize = size + size; - - /* 12-Mar-2010, tatu: Let's actually limit maximum size we are - * prepared to use, to guard against OOME in case of unbounded - * name sets (unique [non-repeating] names) - */ - if (newSize > MAX_TABLE_SIZE) { - /* If this happens, there's no point in either growing or - * shrinking hash areas. Rather, it's better to just clean - * them up for reuse. - */ - _size = 0; - Arrays.fill(_symbols, null); - Arrays.fill(_buckets, null); - _dirty = true; - return; - } - - String[] oldSyms = _symbols; - Bucket[] oldBuckets = _buckets; - _symbols = new String[newSize]; - _buckets = new Bucket[newSize >> 1]; - // Let's update index mask, threshold, now (needed for rehashing) - _indexMask = newSize - 1; - _sizeThreshold += _sizeThreshold; - - int count = 0; // let's do sanity check - - /* Need to do two loops, unfortunately, since spill-over area is - * only half the size: - */ - for (int i = 0; i < size; ++i) { - String symbol = oldSyms[i]; - if (symbol != null) { - ++count; - int index = calcHash(symbol) & _indexMask; - if (_symbols[index] == null) { - _symbols[index] = symbol; - } else { - int bix = index >> 1; - _buckets[bix] = new Bucket(symbol, _buckets[bix]); - } - } - } - - size >>= 1; - for (int i = 0; i < size; ++i) { - Bucket b = oldBuckets[i]; - while (b != null) { - ++count; - String symbol = b.getSymbol(); - int index = calcHash(symbol) & _indexMask; - if (_symbols[index] == null) { - _symbols[index] = symbol; - } else { - int bix = index >> 1; - _buckets[bix] = new Bucket(symbol, _buckets[bix]); - } - b = b.getNext(); - } - } - - if (count != _size) { - throw new Error("Internal error on SymbolTable.rehash(): had "+_size+" entries; now have "+count+"."); - } - } - - /* - /**************************************** - /* Bucket class - /**************************************** - */ - - /** - * This class is a symbol table entry. Each entry acts as a node - * in a linked list. - */ - static final class Bucket { - private final String _symbol; - private final Bucket mNext; - - public Bucket(String symbol, Bucket next) { - _symbol = symbol; - mNext = next; - } - - public String getSymbol() { return _symbol; } - public Bucket getNext() { return mNext; } - - public String find(char[] buf, int start, int len) { - String sym = _symbol; - Bucket b = mNext; - - while (true) { // Inlined equality comparison: - if (sym.length() == len) { - int i = 0; - do { - if (sym.charAt(i) != buf[start+i]) { - break; - } - } while (++i < len); - if (i == len) { - return sym; - } - } - if (b == null) { - break; - } - sym = b.getSymbol(); - b = b.getNext(); - } - return null; - } - - /* 26-Nov-2008, tatu: not used currently; if not used in near future, - * let's just delete it. - */ - /* - public String find(String str) { - String sym = _symbol; - Bucket b = mNext; - - while (true) { - if (sym.equals(str)) { - return sym; - } - if (b == null) { - break; - } - sym = b.getSymbol(); - b = b.getNext(); - } - return null; - } - */ - } -} diff --git a/src/org/codehaus/jackson/sym/Name.java b/src/org/codehaus/jackson/sym/Name.java deleted file mode 100644 index b677876bb9..0000000000 --- a/src/org/codehaus/jackson/sym/Name.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.codehaus.jackson.sym; - -/** - * Base class for tokenized names (key strings in objects) that have - * been tokenized from byte-based input sources (like - * {@link java.io.InputStream}. - * - * @author Tatu Saloranta - */ -public abstract class Name -{ - protected final String mName; - - protected final int mHashCode; - - protected Name(String name, int hashCode) { - mName = name; - mHashCode = hashCode; - } - - public String getName() { return mName; } - - /* - ////////////////////////////////////////////////////////// - // Methods for package/core parser - ////////////////////////////////////////////////////////// - */ - - public abstract boolean equals(int quad1); - - public abstract boolean equals(int quad1, int quad2); - - public abstract boolean equals(int[] quads, int qlen); - - /* - ////////////////////////////////////////////////////////// - // Overridden standard methods - ////////////////////////////////////////////////////////// - */ - - @Override - public String toString() { return mName; } - - @Override - public final int hashCode() { return mHashCode; } - - @Override - public boolean equals(Object o) - { - // Canonical instances, can usually just do identity comparison - return (o == this); - } -} diff --git a/src/org/codehaus/jackson/sym/Name1.java b/src/org/codehaus/jackson/sym/Name1.java deleted file mode 100644 index 6be327a54d..0000000000 --- a/src/org/codehaus/jackson/sym/Name1.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.codehaus.jackson.sym; - -/** - * Specialized implementation of PName: can be used for short Strings - * that consists of at most 4 bytes. Usually this means short - * ascii-only names. - *

- * The reason for such specialized classes is mostly space efficiency; - * and to a lesser degree performance. Both are achieved for short - * Strings by avoiding another level of indirection (via quad arrays) - */ -public final class Name1 - extends Name -{ - final static Name1 sEmptyName = new Name1("", 0, 0); - - final int mQuad; - - Name1(String name, int hash, int quad) - { - super(name, hash); - mQuad = quad; - } - - final static Name1 getEmptyName() { return sEmptyName; } - - public boolean equals(int quad) - { - return (quad == mQuad); - } - - public boolean equals(int quad1, int quad2) - { - return (quad1 == mQuad) && (quad2 == 0); - } - - public boolean equals(int[] quads, int qlen) - { - return (qlen == 1 && quads[0] == mQuad); - } -} diff --git a/src/org/codehaus/jackson/sym/Name2.java b/src/org/codehaus/jackson/sym/Name2.java deleted file mode 100644 index ba6d97e9be..0000000000 --- a/src/org/codehaus/jackson/sym/Name2.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.codehaus.jackson.sym; - -/** - * Specialized implementation of PName: can be used for short Strings - * that consists of 5 to 8 bytes. Usually this means relatively short - * ascii-only names. - *

- * The reason for such specialized classes is mostly space efficiency; - * and to a lesser degree performance. Both are achieved for short - * Strings by avoiding another level of indirection (via quad arrays) - */ -public final class Name2 - extends Name -{ - final int mQuad1; - - final int mQuad2; - - Name2(String name, int hash, int quad1, int quad2) - { - super(name, hash); - mQuad1 = quad1; - mQuad2 = quad2; - } - - public boolean equals(int quad) { return false; } - - public boolean equals(int quad1, int quad2) - { - return (quad1 == mQuad1) && (quad2 == mQuad2); - } - - public boolean equals(int[] quads, int qlen) - { - return (qlen == 2 && quads[0] == mQuad1 && quads[1] == mQuad2); - } -} diff --git a/src/org/codehaus/jackson/sym/Name3.java b/src/org/codehaus/jackson/sym/Name3.java deleted file mode 100644 index d35db6c9af..0000000000 --- a/src/org/codehaus/jackson/sym/Name3.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.codehaus.jackson.sym; - -/** - * Specialized implementation of PName: can be used for short Strings - * that consists of 9 to 12 bytes. It's the longest special purpose - * implementaion; longer ones are expressed using {@link NameN}. - */ -public final class Name3 - extends Name -{ - final int mQuad1; - final int mQuad2; - final int mQuad3; - - Name3(String name, int hash, int q1, int q2, int q3) - { - super(name, hash); - mQuad1 = q1; - mQuad2 = q2; - mQuad3 = q3; - } - - // Implies quad length == 1, never matches - public boolean equals(int quad) { return false; } - - // Implies quad length == 2, never matches - public boolean equals(int quad1, int quad2) { return false; } - - public boolean equals(int[] quads, int qlen) - { - return (qlen == 3) - && (quads[0] == mQuad1) - && (quads[1] == mQuad2) - && (quads[2] == mQuad3); - } -} diff --git a/src/org/codehaus/jackson/sym/NameN.java b/src/org/codehaus/jackson/sym/NameN.java deleted file mode 100644 index b5236f2b53..0000000000 --- a/src/org/codehaus/jackson/sym/NameN.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.codehaus.jackson.sym; - -/** - * Generic implementation of PName used for "long" names, where long - * means that its byte (UTF-8) representation is 13 bytes or more. - */ -public final class NameN - extends Name -{ - final int[] mQuads; - final int mQuadLen; - - NameN(String name, int hash, int[] quads, int quadLen) - { - super(name, hash); - /* We have specialized implementations for shorter - * names, so let's not allow runt instances here - */ - if (quadLen < 3) { - throw new IllegalArgumentException("Qlen must >= 3"); - } - mQuads = quads; - mQuadLen = quadLen; - } - - // Implies quad length == 1, never matches - @Override - public boolean equals(int quad) { return false; } - - // Implies quad length == 2, never matches - @Override - public boolean equals(int quad1, int quad2) { return false; } - - @Override - public boolean equals(int[] quads, int qlen) - { - if (qlen != mQuadLen) { - return false; - } - - /* 26-Nov-2008, tatus: Strange, but it does look like - * unrolling here is counter-productive, reducing - * speed. Perhaps it prevents inlining by HotSpot or - * something... - */ - // Will always have >= 3 quads, can unroll - /* - if (quads[0] == mQuads[0] - && quads[1] == mQuads[1] - && quads[2] == mQuads[2]) { - for (int i = 3; i < qlen; ++i) { - if (quads[i] != mQuads[i]) { - return false; - } - } - return true; - } - */ - - // or simpler way without unrolling: - for (int i = 0; i < qlen; ++i) { - if (quads[i] != mQuads[i]) { - return false; - } - } - return true; - } -} diff --git a/src/org/codehaus/jackson/type/JavaType.java b/src/org/codehaus/jackson/type/JavaType.java deleted file mode 100644 index 78e5e21c75..0000000000 --- a/src/org/codehaus/jackson/type/JavaType.java +++ /dev/null @@ -1,344 +0,0 @@ -package org.codehaus.jackson.type; - -import java.lang.reflect.Modifier; - -/** - * Base class for type token classes used both to contain information - * and as keys for deserializers. - */ -public abstract class JavaType -{ - /** - * This is the nominal type-erased Class that would be close to the - * type represented (but not exactly type, due to type erasure: type - * instance may have more information on this). - * May be an interface or abstract class, so instantiation - * may not be possible. - */ - protected final Class _class; - - protected int _hashCode; - - /** - * Optional handler (codec) that can be attached to indicate - * what to use for handling (serializing, deserializing) values of - * this specific type. - *

- * Note: untyped (i.e. caller has to cast) because it is used for - * different kinds of handlers, with unrelated types. - * - * @since 1.3 - */ - protected Object _valueHandler; - - /** - * Optional handler that can be attached to indicate how to handle - * additional type metadata associated with this type. - *

- * Note: untyped (i.e. caller has to cast) because it is used for - * different kinds of handlers, with unrelated types. - * - * @since 1.5 - */ - protected Object _typeHandler; - - /* - /************************************************* - // Life-cycle - /************************************************* - */ - - protected JavaType(Class clz) - { - _class = clz; - String name = clz.getName(); - _hashCode = name.hashCode(); - } - - /** - * Method that can be called to do a "narrowing" conversions; that is, to return a type with a raw class that is - * assignable to the raw class of this type.If this is not possible, an {@link IllegalArgumentException} is - * thrown.If class is same as the current raw class, instance itself is returned. - * - * @param subclass Undocumented. - * @return Undocumented. - */ - public final JavaType narrowBy(Class subclass) - { - // First: if same raw class, just return this instance - if (subclass == _class) { - return this; - } - // Otherwise, ensure compatibility - _assertSubclass(subclass, _class); - JavaType result = _narrow(subclass); - if (_valueHandler != null) { - result.setValueHandler(_valueHandler); - } - if (_typeHandler != null) { - result.setTypeHandler(_typeHandler); - } - return result; - } - - /** - * More efficient version of {@link #narrowBy}, called by - * internal framework in cases where compatibility checks - * are to be skipped. - * - * @param subclass Undocumented. - * @return Undocumented. - * @since 1.5 - */ - public final JavaType forcedNarrowBy(Class subclass) - { - if (subclass == _class) { // can still optimize for simple case - return this; - } - JavaType result = _narrow(subclass); - if (_valueHandler != null) { - result.setValueHandler(_valueHandler); - } - if (_typeHandler != null) { - result.setTypeHandler(_typeHandler); - } - return result; - } - - /** - * Method that can be called to do a "widening" conversions; that is, to return a type with a raw class that could - * be assigned from this type.If such conversion is not possible, an {@link IllegalArgumentException} is thrown.If - * class is same as the current raw class, instance itself is returned. - * - * @param superclass Undocumented. - * @return Undocumented. - */ - public final JavaType widenBy(Class superclass) - { - // First: if same raw class, just return this instance - if (superclass == _class) { - return this; - } - // Otherwise, ensure compatibility - _assertSubclass(_class, superclass); - return _widen(superclass); - } - - protected abstract JavaType _narrow(Class subclass); - - /** - *

- * Default implementation is just to call {@link #_narrow}, since - * underlying type construction is usually identical - * @param superclass Undocumented. - * @return Undocumented. - */ - protected JavaType _widen(Class superclass) { - return _narrow(superclass); - } - - public abstract JavaType narrowContentsBy(Class contentClass); - - /** - * Method for assigning handler to associate with this type; or - * if null passed, to remove such assignment - * - * @param h Undocumented. - * @since 1.3 - */ - public void setValueHandler(Object h) { - // sanity check, should be assigned just once - if (h != null && _valueHandler != null) { - throw new IllegalStateException("Trying to reset value handler for type ["+toString() - +"]; old handler of type "+_valueHandler.getClass().getName()+", new handler of type "+h.getClass().getName()); - } - _valueHandler = h; - } - - /** - * Method for assigning type handler to associate with this type; or - * if null passed, to remove such assignment - * - * @param h Undocumented. - * @since 1.5 - */ - public void setTypeHandler(Object h) { - // sanity check, should be assigned just once - if (h != null && _typeHandler != null) { - throw new IllegalStateException("Trying to reset type handler for type ["+toString() - +"]; old handler of type "+_typeHandler.getClass().getName()+", new handler of type "+h.getClass().getName()); - } - _typeHandler = h; - } - - /* - /************************************************* - /* Public API - /************************************************* - */ - - public final Class getRawClass() { return _class; } - - /** - * Method that can be used to check whether this type has specified Class as its type erasure.Put another way, - * returns true if instantiation of this Type is given (type-erased) Class. - * - * @param clz Undocumented. - * @return Undocumented. - */ - public final boolean hasRawClass(Class clz) { - return _class == clz; - } - - /** - * @return True if type represented is a container type; this includes - * array, Map and Collection types. - */ - public abstract boolean isContainerType(); - - public boolean isAbstract() { - return Modifier.isAbstract(_class.getModifiers()); - } - - /** - * @return Undocumented. - * @since 1.3 - */ - public boolean isConcrete() { - int mod = _class.getModifiers(); - if ((mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0) { - return true; - } - /* 19-Feb-2010, tatus: Holy mackarel; primitive types - * have 'abstract' flag set... - */ - if (_class.isPrimitive()) { - return true; - } - return false; - } - - public boolean isThrowable() { - return Throwable.class.isAssignableFrom(_class); - } - - public boolean isArrayType() { return false; } - - public final boolean isEnumType() { return _class.isEnum(); } - - public final boolean isInterface() { return _class.isInterface(); } - - public final boolean isPrimitive() { return _class.isPrimitive(); } - - public final boolean isFinal() { return Modifier.isFinal(_class.getModifiers()); } - - /** - * Method for accessing key type for this type, assuming type - * has such a concept (only Map types do) - * @return Undocumented. - */ - public JavaType getKeyType() { return null; } - - /** - * Method for accessing content type of this type, if type has - * such a thing: simple types do not, structured types do - * (like arrays, Collections and Maps) - * @return Undocumented. - */ - public JavaType getContentType() { return null; } - - /** - * Method for checking how many contained types this type has.Contained types are usually generic types, so that - * generic Maps have 2 contained types. - * - * @return Undocumented. - * @since 1.5 - */ - public int containedTypeCount() { return 0; } - - /** - * Method for accessing definitions of contained ("child") - * types. - * - * @param index Index of contained type to return - * - * @return Contained type at index, or null if no such type - * exists (no exception thrown) - * - * @since 1.5 - */ - public JavaType containedType(int index) { return null; } - - /** - * Method for accessing name of type variable in indicated - * position. If no name is bound, will use placeholders (derived - * from 0-based index); if no type variable or argument exists - * with given index, null is returned. - * - * @param index Index of contained type to return - * - * @return Contained type at index, or null if no such type - * exists (no exception thrown) - * - * @since 1.5 - */ - public String containedTypeName(int index) { return null; } - - /** - * Method for accessing value handler associated with this type, if any - * - * @param Undocumented. - * @return Undocumented. - * @since 1.3 - */ - @SuppressWarnings("unchecked") - public T getValueHandler() { return (T) _valueHandler; } - - /** - * Method for accessing type handler associated with this type, if any - * - * @param Undocumented. - * @return Undocumented. - * @since 1.5 - */ - @SuppressWarnings("unchecked") - public T getTypeHandler() { return (T) _typeHandler; } - - /** - * Method that can be used to serialize type into form from which it can be fully deserialized from at a later point - * (using TypeFactory from mapper package).For simple types this is same as calling - * {@link Class#getName}, but for structured types it may additionally contain type information about contents. - * - * @return Undocumented. - * @since 1.5 - */ - public abstract String toCanonical(); - - /* - /************************************************* - /* Helper methods - /************************************************* - */ - - protected void _assertSubclass(Class subclass, Class superClass) - { - if (!_class.isAssignableFrom(subclass)) { - throw new IllegalArgumentException("Class "+subclass.getName()+" is not assignable to "+_class.getName()); - } - } - - /* - /************************************************************** - /* Standard methods; let's make them abstract to force override - /************************************************************** - */ - - @Override - public abstract String toString(); - - @Override - public abstract boolean equals(Object o); - - @Override - public final int hashCode() { return _hashCode; } -} diff --git a/src/org/codehaus/jackson/type/TypeReference.java b/src/org/codehaus/jackson/type/TypeReference.java deleted file mode 100644 index 08c185b36c..0000000000 --- a/src/org/codehaus/jackson/type/TypeReference.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.codehaus.jackson.type; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - -/** - * This class is used to pass full generics type information, and - * avoid problems with type erasure (that basically removes most - * usable type references from runtime Class objects). - * It is based on ideas from - * http://gafter.blogspot.com/2006/12/super-type-tokens.html, - * Additional idea (from a suggestion made in comments of the article) - * is to require bogus implementation of Comparable - * (any such generic interface would do, as long as it forces a method - * with generic type to be implemented). - * to ensure that a Type argument is indeed given. - *

- * Usage is by sub-classing: here is one way to instantiate reference - * to generic type List<Integer>: - *

- *  TypeReference ref = new TypeReference<List<Integer>>() { };
- *
- * which can be passed to methods that accept TypeReference. - */ -public abstract class TypeReference - implements Comparable> -{ - final Type _type; - - protected TypeReference() - { - Type superClass = getClass().getGenericSuperclass(); - if (superClass instanceof Class) { // sanity check, should never happen - throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information"); - } - /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect - * it is possible to make it fail? - * But let's deal with specifc - * case when we know an actual use case, and thereby suitable - * work arounds for valid case(s) and/or error to throw - * on invalid one(s). - */ - _type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; - } - - public Type getType() { return _type; } - - /** - * The only reason we define this method (and require implementation - * of Comparable) is to prevent constructing a - * reference without type information. - */ - public int compareTo(TypeReference o) { - // just need an implementation, not a good one... hence: - return 0; - } -} - diff --git a/src/org/codehaus/jackson/util/BufferRecycler.java b/src/org/codehaus/jackson/util/BufferRecycler.java deleted file mode 100644 index b32a64c695..0000000000 --- a/src/org/codehaus/jackson/util/BufferRecycler.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.codehaus.jackson.util; - -/** - * This is a small utility class, whose main functionality is to allow - * simple reuse of raw byte/char buffers. It is usually used through - * ThreadLocal member of the owning class pointing to - * instance of this class through a SoftReference. The - * end result is a low-overhead GC-cleanable recycling: hopefully - * ideal for use by stream readers. - */ -public final class BufferRecycler -{ - public final static int DEFAULT_WRITE_CONCAT_BUFFER_LEN = 2000; - - public enum ByteBufferType { - READ_IO_BUFFER(4000) - /** - * Buffer used for temporarily storing encoded content; used - * for example by UTF-8 encoding writer - */ - ,WRITE_ENCODING_BUFFER(4000) - - /** - * Buffer used for temporarily concatenating output; used for - * example when requesting output as byte array. - */ - ,WRITE_CONCAT_BUFFER(2000) - ; - - private final int size; - - ByteBufferType(int size) { this.size = size; } - } - - public enum CharBufferType { - TOKEN_BUFFER(2000) // Tokenizable input - ,CONCAT_BUFFER(2000) // concatenated output - ,TEXT_BUFFER(200) // Text content from input - ,NAME_COPY_BUFFER(200) // Temporary buffer for getting name characters - ; - - private final int size; - - CharBufferType(int size) { this.size = size; } - } - - final protected byte[][] mByteBuffers = new byte[ByteBufferType.values().length][]; - final protected char[][] mCharBuffers = new char[CharBufferType.values().length][]; - - public BufferRecycler() { } - - public byte[] allocByteBuffer(ByteBufferType type) - { - int ix = type.ordinal(); - byte[] buffer = mByteBuffers[ix]; - if (buffer == null) { - buffer = balloc(type.size); - } else { - mByteBuffers[ix] = null; - } - return buffer; - } - - public void releaseByteBuffer(ByteBufferType type, byte[] buffer) - { - mByteBuffers[type.ordinal()] = buffer; - } - - public char[] allocCharBuffer(CharBufferType type) - { - return allocCharBuffer(type, 0); - } - - public char[] allocCharBuffer(CharBufferType type, int minSize) - { - if (type.size > minSize) { - minSize = type.size; - } - int ix = type.ordinal(); - char[] buffer = mCharBuffers[ix]; - if (buffer == null || buffer.length < minSize) { - buffer = calloc(minSize); - } else { - mCharBuffers[ix] = null; - } - return buffer; - } - - public void releaseCharBuffer(CharBufferType type, char[] buffer) - { - mCharBuffers[type.ordinal()] = buffer; - } - - /* - ////////////////////////////////////////////////////////////// - // Actual allocations separated for easier debugging/profiling - ////////////////////////////////////////////////////////////// - */ - - private byte[] balloc(int size) - { - return new byte[size]; - } - - private char[] calloc(int size) - { - return new char[size]; - } -} diff --git a/src/org/codehaus/jackson/util/ByteArrayBuilder.java b/src/org/codehaus/jackson/util/ByteArrayBuilder.java deleted file mode 100644 index 08fcfb34e4..0000000000 --- a/src/org/codehaus/jackson/util/ByteArrayBuilder.java +++ /dev/null @@ -1,234 +0,0 @@ -/* Jackson JSON-processor. - * - * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi - * - * Licensed under the License specified in file LICENSE, included with - * the source code and binary code bundles. - * You may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.codehaus.jackson.util; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.*; - -/** - * Helper class that is similar to {@link java.io.ByteArrayOutputStream} - * in usage, but more geared to Jackson use cases internally. - * Specific changes include segment storage (no need to have linear - * backing buffer, can avoid reallocs, copying), as well API - * not based on {@link java.io.OutputStream}. In short, a very much - * specialized builder object. - *

- * Since version 1.5, also implements {@link OutputStream} to allow - * efficient aggregation of output content as a byte array, similar - * to how {@link java.io.ByteArrayOutputStream} works, but somewhat more - * efficiently for many use cases. - */ -public final class ByteArrayBuilder - extends OutputStream -{ - private final static byte[] NO_BYTES = new byte[0]; - - /** - * Size of the first block we will allocate. - */ - private final static int INITIAL_BLOCK_SIZE = 500; - - /** - * Maximum block size we will use for individual non-aggregated - * blocks. Let's limit to using 256k chunks. - */ - private final static int MAX_BLOCK_SIZE = (1 << 18); - - final static int DEFAULT_BLOCK_ARRAY_SIZE = 40; - - /** - * Optional buffer recycler instance that we can use for allocating - * the first block. - * - * @since 1.5 - */ - private final BufferRecycler _bufferRecycler; - - private final LinkedList _pastBlocks = new LinkedList(); - - /** - * Number of bytes within byte arrays in {@link _pastBlocks}. - */ - private int _pastLen; - - private byte[] _currBlock; - - private int _currBlockPtr; - - public ByteArrayBuilder() { this(null); } - - public ByteArrayBuilder(BufferRecycler br) { this(br, INITIAL_BLOCK_SIZE); } - - public ByteArrayBuilder(int firstBlockSize) { this(null, firstBlockSize); } - - public ByteArrayBuilder(BufferRecycler br, int firstBlockSize) - { - _bufferRecycler = br; - if (br == null) { - _currBlock = new byte[firstBlockSize]; - } else { - _currBlock = br.allocByteBuffer(BufferRecycler.ByteBufferType.WRITE_CONCAT_BUFFER); - } - } - - public void reset() - { - _pastLen = 0; - _currBlockPtr = 0; - - if (!_pastBlocks.isEmpty()) { - _currBlock = _pastBlocks.getLast(); - _pastBlocks.clear(); - } - } - - /** - * Clean up method to call to release all buffers this object may be - * using. After calling the method, no other accessors can be used (and - * attempt to do so may result in an exception) - */ - public void release() { - reset(); - if (_bufferRecycler != null && _currBlock != null) { - _bufferRecycler.releaseByteBuffer(BufferRecycler.ByteBufferType.WRITE_CONCAT_BUFFER, _currBlock); - } - } - - public void append(int i) - { - byte b = (byte) i; - if (_currBlockPtr >= _currBlock.length) { - _allocMore(); - } - _currBlock[_currBlockPtr++] = b; - } - - public void appendTwoBytes(int b16) - { - if ((_currBlockPtr + 1) < _currBlock.length) { - _currBlock[_currBlockPtr++] = (byte) (b16 >> 8); - _currBlock[_currBlockPtr++] = (byte) b16; - } else { - append(b16 >> 8); - append(b16); - } - } - - public void appendThreeBytes(int b24) - { - if ((_currBlockPtr + 2) < _currBlock.length) { - _currBlock[_currBlockPtr++] = (byte) (b24 >> 16); - _currBlock[_currBlockPtr++] = (byte) (b24 >> 8); - _currBlock[_currBlockPtr++] = (byte) b24; - } else { - append(b24 >> 16); - append(b24 >> 8); - append(b24); - } - } - - /** - * Method called when results are finalized and we can get the - * full aggregated result buffer to return to the caller - * @return Undocumented. - */ - public byte[] toByteArray() - { - int totalLen = _pastLen + _currBlockPtr; - - if (totalLen == 0) { // quick check: nothing aggregated? - return NO_BYTES; - } - - byte[] result = new byte[totalLen]; - int offset = 0; - - for (byte[] block : _pastBlocks) { - int len = block.length; - System.arraycopy(block, 0, result, offset, len); - offset += len; - } - System.arraycopy(_currBlock, 0, result, offset, _currBlockPtr); - offset += _currBlockPtr; - if (offset != totalLen) { // just a sanity check - throw new RuntimeException("Internal error: total len assumed to be "+totalLen+", copied "+offset+" bytes"); - } - // Let's only reset if there's sizable use, otherwise will get reset later on - if (!_pastBlocks.isEmpty()) { - reset(); - } - return result; - } - - private void _allocMore() - { - _pastLen += _currBlock.length; - - /* Let's allocate block that's half the total size, except - * never smaller than twice the initial block size. - * The idea is just to grow with reasonable rate, to optimize - * between minimal number of chunks and minimal amount of - * wasted space. - */ - int newSize = Math.max((_pastLen >> 1), (INITIAL_BLOCK_SIZE + INITIAL_BLOCK_SIZE)); - // plus not to exceed max we define... - if (newSize > MAX_BLOCK_SIZE) { - newSize = MAX_BLOCK_SIZE; - } - _pastBlocks.add(_currBlock); - _currBlock = new byte[newSize]; - _currBlockPtr = 0; - } - - /* - /******************************************************* - /* OutputStream implementation - /******************************************************* - */ - - @Override - public void write(byte[] b) { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int len) - { - while (true) { - int max = _currBlock.length - _currBlockPtr; - int toCopy = Math.min(max, len); - if (toCopy > 0) { - System.arraycopy(b, off, _currBlock, _currBlockPtr, toCopy); - off += toCopy; - _currBlockPtr += toCopy; - len -= toCopy; - } - if (len <= 0) break; - _allocMore(); - } - } - - @Override - public void write(int b) throws IOException { - append(b); - } - - @Override public void close() { /* NOP */ } - - @Override public void flush() { /* NOP */ } -} - diff --git a/src/org/codehaus/jackson/util/CharTypes.java b/src/org/codehaus/jackson/util/CharTypes.java deleted file mode 100644 index 8fee6a44a9..0000000000 --- a/src/org/codehaus/jackson/util/CharTypes.java +++ /dev/null @@ -1,193 +0,0 @@ -package org.codehaus.jackson.util; - -import java.util.Arrays; - -public final class CharTypes -{ - final static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); - - /** - * Lookup table used for determining which input characters - * need special handling when contained in text segment. - */ - final static int[] sInputCodes; - static { - /* 96 would do for most cases (backslash is ascii 94) - * but if we want to do lookups by raw bytes it's better - * to have full table - */ - int[] table = new int[256]; - // Control chars and non-space white space are not allowed unquoted - for (int i = 0; i < 32; ++i) { - table[i] = -1; - } - // And then string end and quote markers are special too - table['"'] = 1; - table['\\'] = 1; - sInputCodes = table; - } - - /** - * Additionally we can combine UTF-8 decoding info into similar - * data table. - */ - final static int[] sInputCodesUtf8; - static { - int[] table = new int[sInputCodes.length]; - System.arraycopy(sInputCodes, 0, table, 0, sInputCodes.length); - for (int c = 128; c < 256; ++c) { - int code; - - // We'll add number of bytes needed for decoding - if ((c & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF) - code = 2; - } else if ((c & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF) - code = 3; - } else if ((c & 0xF8) == 0xF0) { - // 4 bytes; double-char with surrogates and all... - code = 4; - } else { - // And -1 seems like a good "universal" error marker... - code = -1; - } - table[c] = code; - } - sInputCodesUtf8 = table; - } - - /** - * To support non-default (and -standard) unquoted field names mode, - * need to have alternate checking. - * Basically this is list of 8-bit ascii characters that are legal - * as part of Javascript identifier - * - * @since 1.2 - */ - final static int[] sInputCodesJsNames; - static { - int[] table = new int[256]; - // Default is "not a name char", mark ones that are - Arrays.fill(table, -1); - // Assume rules with JS same as Java (change if/as needed) - for (int i = 33; i < 256; ++i) { - if (Character.isJavaIdentifierPart((char) i)) { - table[i] = 0; - } - } - sInputCodesJsNames = table; - } - - /** - * This table is similar to Latin1, except that it marks all "high-bit" - * code as ok. They will be validated at a later point, when decoding - * name - */ - final static int[] sInputCodesUtf8JsNames; - static { - int[] table = new int[256]; - // start with 8-bit JS names - System.arraycopy(sInputCodesJsNames, 0, table, 0, sInputCodesJsNames.length); - Arrays.fill(table, 128, 128, 0); - sInputCodesUtf8JsNames = table; - } - - /** - * Decoding table used to quickly determine characters that are - * relevant within comment content - */ - final static int[] sInputCodesComment = new int[256]; - static { - // but first: let's start with UTF-8 multi-byte markers: - System.arraycopy(sInputCodesUtf8, 128, sInputCodesComment, 128, 128); - - // default (0) means "ok" (skip); -1 invalid, others marked by char itself - Arrays.fill(sInputCodesComment, 0, 32, -1); // invalid white space - sInputCodesComment['\t'] = 0; // tab is still fine - sInputCodesComment['\n'] = '\n'; // lf/cr need to be observed, ends cpp comment - sInputCodesComment['\r'] = '\r'; - sInputCodesComment['*'] = '*'; // end marker for c-style comments - } - - /** - * Lookup table used for determining which output characters - * need to be quoted. - */ - final static int[] sOutputEscapes; - static { - int[] table = new int[256]; - // Control chars need generic escape sequence - for (int i = 0; i < 32; ++i) { - table[i] = -(i + 1); - } - /* Others (and some within that range too) have explicit shorter - * sequences - */ - table['"'] = '"'; - table['\\'] = '\\'; - // Escaping of slash is optional, so let's not add it - table[0x08] = 'b'; - table[0x09] = 't'; - table[0x0C] = 'f'; - table[0x0A] = 'n'; - table[0x0D] = 'r'; - sOutputEscapes = table; - } - - /** - * Lookup table for the first 128 Unicode characters (7-bit ascii) - * range. For actual hex digits, contains corresponding value; - * for others -1. - */ - final static int[] sHexValues = new int[128]; - static { - Arrays.fill(sHexValues, -1); - for (int i = 0; i < 10; ++i) { - sHexValues['0' + i] = i; - } - for (int i = 0; i < 6; ++i) { - sHexValues['a' + i] = 10 + i; - sHexValues['A' + i] = 10 + i; - } - } - - public final static int[] getInputCodeLatin1() { return sInputCodes; } - public final static int[] getInputCodeUtf8() { return sInputCodesUtf8; } - - public final static int[] getInputCodeLatin1JsNames() { return sInputCodesJsNames; } - public final static int[] getInputCodeUtf8JsNames() { return sInputCodesUtf8JsNames; } - - public final static int[] getInputCodeComment() { return sInputCodesComment; } - public final static int[] getOutputEscapes() { return sOutputEscapes; } - - public static int charToHex(int ch) - { - return (ch > 127) ? -1 : sHexValues[ch]; - } - - public static void appendQuoted(StringBuilder sb, String content) - { - final int[] escCodes = sOutputEscapes; - int escLen = escCodes.length; - for (int i = 0, len = content.length(); i < len; ++i) { - char c = content.charAt(i); - if (c >= escLen || escCodes[c] == 0) { - sb.append(c); - continue; - } - sb.append('\\'); - int escCode = escCodes[c]; - if (escCode < 0) { // generic quoting (hex value) - // We know that it has to fit in just 2 hex chars - sb.append('u'); - sb.append('0'); - sb.append('0'); - int value = -(escCode + 1); - sb.append(HEX_CHARS[value >> 4]); - sb.append(HEX_CHARS[value & 0xF]); - } else { // "named", i.e. prepend with slash - sb.append((char) escCode); - } - } - } -} - diff --git a/src/org/codehaus/jackson/util/InternCache.java b/src/org/codehaus/jackson/util/InternCache.java deleted file mode 100644 index 0246409626..0000000000 --- a/src/org/codehaus/jackson/util/InternCache.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.codehaus.jackson.util; - -import java.util.Map; -import java.util.LinkedHashMap; - -/** - * Singleton class that adds a simple first-level cache in front of - * regular String.intern() functionality. This is done as a minor - * performance optimization, to avoid calling native intern() method - * in cases where same String is being interned multiple times. - *

- * Note: that this class extends {@link LinkedHashMap} is an implementation - * detail -- no code should ever directly call Map methods. - */ -@SuppressWarnings("serial") -public final class InternCache - extends LinkedHashMap -{ - /** - * Size to use is somewhat arbitrary, so let's choose something that's - * neither too small (low hit ratio) nor too large (waste of memory) - */ - private final static int MAX_ENTRIES = 192; - - public final static InternCache instance = new InternCache(); - - private InternCache() { - super(MAX_ENTRIES, 0.8f, true); - } - - protected boolean removeEldestEntry(Map.Entry eldest) - { - return size() > MAX_ENTRIES; - } - - public synchronized String intern(String input) - { - String result = get(input); - if (result == null) { - result = input.intern(); - put(result, result); - } - return result; - } - - -} - diff --git a/src/org/codehaus/jackson/util/JsonGeneratorDelegate.java b/src/org/codehaus/jackson/util/JsonGeneratorDelegate.java deleted file mode 100644 index 186ced2c72..0000000000 --- a/src/org/codehaus/jackson/util/JsonGeneratorDelegate.java +++ /dev/null @@ -1,225 +0,0 @@ -package org.codehaus.jackson.util; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.codehaus.jackson.Base64Variant; -import org.codehaus.jackson.JsonGenerationException; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonNode; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonProcessingException; -import org.codehaus.jackson.JsonStreamContext; -import org.codehaus.jackson.ObjectCodec; - -public class JsonGeneratorDelegate extends JsonGenerator -{ - /** - * Delegate object that method calls are delegated to. - */ - protected JsonGenerator delegate; - - public JsonGeneratorDelegate(JsonGenerator d) { - delegate = d; - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException { - delegate.copyCurrentEvent(jp); - } - - @Override - public void copyCurrentStructure(JsonParser jp) throws IOException, JsonProcessingException { - delegate.copyCurrentStructure(jp); - } - - @Override - public JsonGenerator disable(Feature f) { - return delegate.disable(f); - } - - @Override - public JsonGenerator enable(Feature f) { - return delegate.enable(f); - } - - @Override - public void flush() throws IOException { - delegate.flush(); - } - - @Override - public ObjectCodec getCodec() { - return delegate.getCodec(); - } - - @Override - public JsonStreamContext getOutputContext() { - return delegate.getOutputContext(); - } - - @Override - public boolean isClosed() { - return delegate.isClosed(); - } - - @Override - public boolean isEnabled(Feature f) { - return delegate.isEnabled(f); - } - - @Override - public JsonGenerator setCodec(ObjectCodec oc) { - delegate.setCodec(oc); - return this; - } - - @Override - public JsonGenerator useDefaultPrettyPrinter() { - delegate.useDefaultPrettyPrinter(); - return this; - } - - @Override - public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) - throws IOException, JsonGenerationException - { - delegate.writeBinary(b64variant, data, offset, len); - } - - @Override - public void writeBoolean(boolean state) throws IOException, JsonGenerationException { - delegate.writeBoolean(state); - } - - @Override - public void writeEndArray() throws IOException, JsonGenerationException { - delegate.writeEndArray(); - } - - @Override - public void writeEndObject() throws IOException, JsonGenerationException { - delegate.writeEndObject(); - } - - @Override - public void writeFieldName(String name) throws IOException, - JsonGenerationException { - delegate.writeFieldName(name); - } - - @Override - public void writeNull() throws IOException, JsonGenerationException { - delegate.writeNull(); - } - - @Override - public void writeNumber(int v) throws IOException, JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(long v) throws IOException, JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(BigInteger v) throws IOException, - JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(double v) throws IOException, - JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(float v) throws IOException, - JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(BigDecimal v) throws IOException, - JsonGenerationException { - delegate.writeNumber(v); - } - - @Override - public void writeNumber(String encodedValue) throws IOException, JsonGenerationException, UnsupportedOperationException { - delegate.writeNumber(encodedValue); - } - - @Override - public void writeObject(Object pojo) throws IOException,JsonProcessingException { - delegate.writeObject(pojo); - } - - @Override - public void writeRaw(String text) throws IOException, JsonGenerationException { - delegate.writeRaw(text); - } - - @Override - public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException { - delegate.writeRaw(text, offset, len); - } - - @Override - public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException { - delegate.writeRaw(text, offset, len); - } - - @Override - public void writeRaw(char c) throws IOException, JsonGenerationException { - delegate.writeRaw(c); - } - - @Override - public void writeRawValue(String text) throws IOException, JsonGenerationException { - delegate.writeRawValue(text); - } - - @Override - public void writeRawValue(String text, int offset, int len) throws IOException, JsonGenerationException { - delegate.writeRawValue(text, offset, len); - } - - @Override - public void writeRawValue(char[] text, int offset, int len) throws IOException, JsonGenerationException { - delegate.writeRawValue(text, offset, len); - } - - @Override - public void writeStartArray() throws IOException, JsonGenerationException { - delegate.writeStartArray(); - } - - @Override - public void writeStartObject() throws IOException, JsonGenerationException { - delegate.writeStartObject(); - } - - @Override - public void writeString(String text) throws IOException,JsonGenerationException { - delegate.writeString(text); - } - - @Override - public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException { - delegate.writeString(text, offset, len); - } - - @Override - public void writeTree(JsonNode rootNode) throws IOException, JsonProcessingException { - delegate.writeTree(rootNode); - } -} diff --git a/src/org/codehaus/jackson/util/JsonParserDelegate.java b/src/org/codehaus/jackson/util/JsonParserDelegate.java deleted file mode 100644 index 51e564d2a3..0000000000 --- a/src/org/codehaus/jackson/util/JsonParserDelegate.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.codehaus.jackson.util; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.codehaus.jackson.*; - -/** - * Helper class that implements - * delegation pattern for {@link JsonParser}, - * to allow for simple overridability of basic parsing functionality. - * The idea is that any functionality to be modified can be simply - * overridden; and anything else will be delegated by default. - * - * @since 1.4 - */ -public class JsonParserDelegate extends JsonParser -{ - /** - * Delegate object that method calls are delegated to. - */ - protected JsonParser delegate; - - public JsonParserDelegate(JsonParser d) { - delegate = d; - } - - /* - /************************************************** - /* Public API, configuration - /************************************************** - */ - - @Override - public void setCodec(ObjectCodec c) { - delegate.setCodec(c); - } - - @Override - public ObjectCodec getCodec() { - return delegate.getCodec(); - } - - public JsonParser enable(Feature f) { - delegate.enable(f); - return this; - } - - public JsonParser disable(Feature f) { - delegate.disable(f); - return this; - } - - public boolean isEnabled(Feature f) { - return delegate.isEnabled(f); - } - - /* - /************************************************** - /* Closeable impl - /************************************************** - */ - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isClosed() { - return delegate.isClosed(); - } - - /* - /************************************************** - /* Public API, token accessors - /************************************************** - */ - - public JsonToken getCurrentToken() { - return delegate.getCurrentToken(); - } - - public boolean hasCurrentToken() { - return delegate.hasCurrentToken(); - } - - public void clearCurrentToken() { - delegate.clearCurrentToken(); - } - - @Override - public String getCurrentName() throws IOException, JsonParseException { - return delegate.getCurrentName(); - } - - @Override - public JsonLocation getCurrentLocation() { - return delegate.getCurrentLocation(); - } - - @Override - public JsonToken getLastClearedToken() { - return delegate.getLastClearedToken(); - } - - @Override - public JsonStreamContext getParsingContext() { - return delegate.getParsingContext(); - } - - /* - /************************************************** - /* Public API, access to token information, text - /************************************************** - */ - - @Override - public String getText() throws IOException, JsonParseException { - return delegate.getText(); - } - - @Override - public char[] getTextCharacters() throws IOException, JsonParseException { - return delegate.getTextCharacters(); - } - - @Override - public int getTextLength() throws IOException, JsonParseException { - return delegate.getTextLength(); - } - - @Override - public int getTextOffset() throws IOException, JsonParseException { - return delegate.getTextOffset(); - } - - - /* - /************************************************** - /* Public API, access to token information, numeric - /************************************************** - */ - - @Override - public BigInteger getBigIntegerValue() throws IOException,JsonParseException { - return delegate.getBigIntegerValue(); - } - - @Override - public byte getByteValue() throws IOException, JsonParseException { - return delegate.getByteValue(); - } - - @Override - public short getShortValue() throws IOException, JsonParseException { - return delegate.getShortValue(); - } - - @Override - public BigDecimal getDecimalValue() throws IOException, JsonParseException { - return delegate.getDecimalValue(); - } - - @Override - public double getDoubleValue() throws IOException, JsonParseException { - return delegate.getDoubleValue(); - } - - @Override - public float getFloatValue() throws IOException, JsonParseException { - return delegate.getFloatValue(); - } - - @Override - public int getIntValue() throws IOException, JsonParseException { - return delegate.getIntValue(); - } - - @Override - public long getLongValue() throws IOException, JsonParseException { - return delegate.getLongValue(); - } - - @Override - public NumberType getNumberType() throws IOException, JsonParseException { - return delegate.getNumberType(); - } - - @Override - public Number getNumberValue() throws IOException, JsonParseException { - return delegate.getNumberValue(); - } - - @Override - public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException { - return delegate.getBinaryValue(b64variant); - } - - @Override - public JsonLocation getTokenLocation() { - return delegate.getTokenLocation(); - } - - @Override - public JsonToken nextToken() throws IOException, JsonParseException { - return delegate.nextToken(); - } - - @Override - public JsonParser skipChildren() throws IOException, JsonParseException { - delegate.skipChildren(); - // NOTE: must NOT delegate this method to delegate, needs to be self-reference for chaining - return this; - } -} diff --git a/src/org/codehaus/jackson/util/JsonParserSequence.java b/src/org/codehaus/jackson/util/JsonParserSequence.java deleted file mode 100644 index 422ad86205..0000000000 --- a/src/org/codehaus/jackson/util/JsonParserSequence.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.codehaus.jackson.util; - -import java.io.IOException; -import java.util.*; - -import org.codehaus.jackson.*; - -/** - * Helper class that can be used to sequence multiple physical - * {@link JsonParser}s to create a single logical sequence of - * tokens, as a single {@link JsonParser}. - *

- * Fairly simple use of {@link JsonParserDelegate}: only need - * to override {@link #nextToken} to handle transition - * - * @author tatu - * @since 1.5 - */ -public class JsonParserSequence extends JsonParserDelegate -{ - /** - * Parsers other than the first one (which is initially assigned - * as delegate) - */ - protected final JsonParser[] _parsers; - - /** - * Index of the next parser in {@link #_parsers}. - */ - protected int _nextParser; - - /* - ******************************************************* - * Construction - ******************************************************* - */ - - protected JsonParserSequence(JsonParser[] parsers) - { - super(parsers[0]); - _parsers = parsers; - _nextParser = 1; - } - - /** - * Method that will construct a parser (possibly a sequence) that contains all given sub-parsers.All parsers given - * are checked to see if they are sequences: and if so, they will be "flattened", that is, contained parsers are - * directly added in a new sequence instead of adding sequences within sequences.This is done to minimize delegation - * depth, ideally only having just a single level of delegation. - * - * @param first Undocumented. - * @param second Undocumented. - * @return Undocumented. - */ - public static JsonParserSequence createFlattened(JsonParser first, JsonParser second) - { - if (!(first instanceof JsonParserSequence || second instanceof JsonParserSequence)) { - // simple: - return new JsonParserSequence(new JsonParser[] { first, second }); - } - ArrayList p = new ArrayList(); - if (first instanceof JsonParserSequence) { - ((JsonParserSequence) first).addFlattenedActiveParsers(p); - } else { - p.add(first); - } - if (second instanceof JsonParserSequence) { - ((JsonParserSequence) second).addFlattenedActiveParsers(p); - } else { - p.add(second); - } - return new JsonParserSequence(p.toArray(new JsonParser[p.size()])); - } - - protected void addFlattenedActiveParsers(List result) - { - for (int i = _nextParser-1, len = _parsers.length; i < len; ++i) { - JsonParser p = _parsers[i]; - if (p instanceof JsonParserSequence) { - ((JsonParserSequence) p).addFlattenedActiveParsers(result); - } else { - result.add(p); - } - } - } - - /* - ******************************************************* - * Overridden methods, needed: cases where default - * delegation does not work - ******************************************************* - */ - - @Override - public void close() throws IOException - { - do { - delegate.close(); - } while (switchToNext()); - } - - @Override - public JsonToken nextToken() throws IOException, JsonParseException - { - JsonToken t = delegate.nextToken(); - if (t != null) return t; - while (switchToNext()) { - t = delegate.nextToken(); - if (t != null) return t; - } - return null; - } - - /* - /******************************************************* - /* Additional extended API - /******************************************************* - */ - - /** - * Method that is most useful for debugging or testing; - * returns actual number of underlying parsers sequence - * was constructed with (nor just ones remaining active) - * @return Undocumented. - */ - public int containedParsersCount() { - return _parsers.length; - } - - /* - /******************************************************* - /* Helper methods - /******************************************************* - */ - - /** - * Method that will switch active parser from the current one - * to next parser in sequence, if there is another parser left, - * making this the new delegate. Old delegate is returned if - * switch succeeds. - * - * @return True if switch succeeded; false otherwise - */ - protected boolean switchToNext() - { - if (_nextParser >= _parsers.length) { - return false; - } - delegate = _parsers[_nextParser++]; - return true; - } -} diff --git a/src/org/codehaus/jackson/util/TextBuffer.java b/src/org/codehaus/jackson/util/TextBuffer.java deleted file mode 100644 index f01128f314..0000000000 --- a/src/org/codehaus/jackson/util/TextBuffer.java +++ /dev/null @@ -1,640 +0,0 @@ -package org.codehaus.jackson.util; - -import java.math.BigDecimal; -import java.util.ArrayList; - -/** - * TextBuffer is a class similar to {@link StringBuffer}, with - * following differences: - *

    - *
  • TextBuffer uses segments character arrays, to avoid having - * to do additional array copies when array is not big enough. - * This means that only reallocating that is necessary is done only once: - * if and when caller - * wants to access contents in a linear array (char[], String). - *
  • -*
  • TextBuffer can also be initialized in "shared mode", in which -* it will just act as a wrapper to a single char array managed -* by another object (like parser that owns it) - *
  • - *
  • TextBuffer is not synchronized. - *
  • - *
- */ -public final class TextBuffer -{ - final static char[] NO_CHARS = new char[0]; - - /** - * Let's limit maximum segment length to something sensible - * like 256k - */ - final static int MAX_SEGMENT_LEN = 0x40000; - - /* - ////////////////////////////// - // Configuration: - ////////////////////////////// - */ - - private final BufferRecycler _allocator; - - /* - ////////////////////////////// - // Shared input buffers - ////////////////////////////// - */ - - /** - * Shared input buffer; stored here in case some input can be returned - * as is, without being copied to collector's own buffers. Note that - * this is read-only for this Object. - */ - private char[] _inputBuffer; - - /** - * Character offset of first char in input buffer; -1 to indicate - * that input buffer currently does not contain any useful char data - */ - private int _inputStart; - - private int _inputLen; - - /* - ////////////////////////////////////////////////// - // Aggregation segments (when not using input buf) - ////////////////////////////////////////////////// - */ - - /** - * List of segments prior to currently active segment. - */ - private ArrayList _segments; - - /** - * Flag that indicates whether _seqments is non-empty - */ - private boolean _hasSegments = false; - - // // // Currently used segment; not (yet) contained in _seqments - - /** - * Amount of characters in segments in {@link _segments} - */ - private int _segmentSize; - - private char[] _currentSegment; - - /** - * Number of characters in currently active (last) segment - */ - private int _currentSize; - - /* - ////////////////////////////////////////////////// - // Caching of results - ////////////////////////////////////////////////// - */ - - /** - * String that will be constructed when the whole contents are - * needed; will be temporarily stored in case asked for again. - */ - private String _resultString; - - private char[] _resultArray; - - /* - ////////////////////////////////////////////// - // Life-cycle - ////////////////////////////////////////////// - */ - - public TextBuffer(BufferRecycler allocator) - { - _allocator = allocator; - } - - /** - * Method called to indicate that the underlying buffers should now - * be recycled if they haven't yet been recycled. Although caller - * can still use this text buffer, it is not advisable to call this - * method if that is likely, since next time a buffer is needed, - * buffers need to reallocated. - * Note: calling this method automatically also clears contents - * of the buffer. - */ - public void releaseBuffers() - { - if (_allocator != null && _currentSegment != null) { - // First, let's get rid of all but the largest char array - resetWithEmpty(); - // And then return that array - char[] buf = _currentSegment; - _currentSegment = null; - _allocator.releaseCharBuffer(BufferRecycler.CharBufferType.TEXT_BUFFER, buf); - } - } - - /** - * Method called to clear out any content text buffer may have, and - * initializes buffer to use non-shared data. - */ - public void resetWithEmpty() - { - _inputBuffer = null; - _inputStart = -1; // indicates shared buffer not used - _inputLen = 0; - - _resultString = null; - _resultArray = null; - - // And then reset internal input buffers, if necessary: - if (_hasSegments) { - clearSegments(); - } - _currentSize = 0; - } - - /** - * Method called to initialize the buffer with a shared copy of data; this means that buffer will just have pointers - * to actual data.It also means that if anything is to be appended to the buffer, it will first have to unshare it - * (make a local copy). - * - * @param buf Undocumented. - * @param start Undocumented. - * @param len Undocumented. - */ - public void resetWithShared(char[] buf, int start, int len) - { - // First, let's clear intermediate values, if any: - _resultString = null; - _resultArray = null; - - // Then let's mark things we need about input buffer - _inputBuffer = buf; - _inputStart = start; - _inputLen = len; - - // And then reset internal input buffers, if necessary: - if (_hasSegments) { - clearSegments(); - } - } - - public void resetWithCopy(char[] buf, int start, int len) - { - _inputBuffer = null; - _inputStart = -1; // indicates shared buffer not used - _inputLen = 0; - - _resultString = null; - _resultArray = null; - - // And then reset internal input buffers, if necessary: - if (_hasSegments) { - clearSegments(); - } else if (_currentSegment == null) { - _currentSegment = findBuffer(len); - } - _currentSize = _segmentSize = 0; - append(buf, start, len); - } - - /** - * Helper method used to find a buffer to use, ideally one - * recycled earlier. - */ - private final char[] findBuffer(int needed) - { - return _allocator.allocCharBuffer(BufferRecycler.CharBufferType.TEXT_BUFFER, needed); - } - - private final void clearSegments() - { - _hasSegments = false; - /* Let's start using _last_ segment from list; for one, it's - * the biggest one, and it's also most likely to be cached - */ - /* 28-Aug-2009, tatu: Actually, the current segment should - * be the biggest one, already - */ - //_currentSegment = _segments.get(_segments.size() - 1); - _segments.clear(); - _currentSize = _segmentSize = 0; - } - - /* - ////////////////////////////////////////////// - // Accessors for implementing public interface - ////////////////////////////////////////////// - */ - - /** - * @return Number of characters currently stored by this collector - */ - public int size() { - if (_inputStart >= 0) { // shared copy from input buf - return _inputLen; - } - // local segmented buffers - return _segmentSize + _currentSize; - } - - public int getTextOffset() - { - /* Only shared input buffer can have non-zero offset; buffer - * segments start at 0, and if we have to create a combo buffer, - * that too will start from beginning of the buffer - */ - return (_inputStart >= 0) ? _inputStart : 0; - } - - public char[] getTextBuffer() - { - // Are we just using shared input buffer? - if (_inputStart >= 0) { - return _inputBuffer; - } - // Nope; but does it fit in just one segment? - if (!_hasSegments) { - return _currentSegment; - } - // Nope, need to have/create a non-segmented array and return it - return contentsAsArray(); - } - - /* - ////////////////////////////////////////////// - // Other accessors: - ////////////////////////////////////////////// - */ - - public String contentsAsString() - { - if (_resultString == null) { - // Has array been requested? Can make a shortcut, if so: - if (_resultArray != null) { - _resultString = new String(_resultArray); - } else { - // Do we use shared array? - if (_inputStart >= 0) { - if (_inputLen < 1) { - return (_resultString = ""); - } - _resultString = new String(_inputBuffer, _inputStart, _inputLen); - } else { // nope... need to copy - // But first, let's see if we have just one buffer - int segLen = _segmentSize; - int currLen = _currentSize; - - if (segLen == 0) { // yup - _resultString = (currLen == 0) ? "" : new String(_currentSegment, 0, currLen); - } else { // no, need to combine - StringBuilder sb = new StringBuilder(segLen + currLen); - // First stored segments - if (_segments != null) { - for (int i = 0, len = _segments.size(); i < len; ++i) { - char[] curr = _segments.get(i); - sb.append(curr, 0, curr.length); - } - } - // And finally, current segment: - sb.append(_currentSegment, 0, _currentSize); - _resultString = sb.toString(); - } - } - } - } - return _resultString; - } - - public char[] contentsAsArray() - { - char[] result = _resultArray; - if (result == null) { - _resultArray = result = buildResultArray(); - } - return result; - } - - /** - * Convenience method for converting contents of the buffer - * into a {@link BigDecimal}. - * @return Undocumented. - */ - public BigDecimal contentsAsDecimal() - throws NumberFormatException - { - // Already got a pre-cut array? - if (_resultArray != null) { - return new BigDecimal(_resultArray); - } - // Or a shared buffer? - if (_inputStart >= 0) { - return new BigDecimal(_inputBuffer, _inputStart, _inputLen); - } - // Or if not, just a single buffer (the usual case) - if (_segmentSize == 0) { - return new BigDecimal(_currentSegment, 0, _currentSize); - } - // If not, let's just get it aggregated... - return new BigDecimal(contentsAsArray()); - } - - /** - * Convenience method for converting contents of the buffer - * into a Double value. - * @return Undocumented. - */ - public double contentsAsDouble() - throws NumberFormatException - { - return Double.parseDouble(contentsAsString()); - } - - /* - ////////////////////////////////////////////// - // Public mutators: - ////////////////////////////////////////////// - */ - - /** - * Method called to make sure that buffer is not using shared input - * buffer; if it is, it will copy such contents to private buffer. - */ - public void ensureNotShared() { - if (_inputStart >= 0) { - unshare(16); - } - } - - public void append(char c) { - // Using shared buffer so far? - if (_inputStart >= 0) { - unshare(16); - } - _resultString = null; - _resultArray = null; - // Room in current segment? - char[] curr = _currentSegment; - if (_currentSize >= curr.length) { - expand(1); - curr = _currentSegment; - } - curr[_currentSize++] = c; - } - - public void append(char[] c, int start, int len) - { - // Can't append to shared buf (sanity check) - if (_inputStart >= 0) { - unshare(len); - } - _resultString = null; - _resultArray = null; - - // Room in current segment? - char[] curr = _currentSegment; - int max = curr.length - _currentSize; - - if (max >= len) { - System.arraycopy(c, start, curr, _currentSize, len); - _currentSize += len; - } else { - // No room for all, need to copy part(s): - if (max > 0) { - System.arraycopy(c, start, curr, _currentSize, max); - start += max; - len -= max; - } - // And then allocate new segment; we are guaranteed to now - // have enough room in segment. - expand(len); // note: curr != _currentSegment after this - System.arraycopy(c, start, _currentSegment, 0, len); - _currentSize = len; - } - } - - public void append(String str, int offset, int len) - { - // Can't append to shared buf (sanity check) - if (_inputStart >= 0) { - unshare(len); - } - _resultString = null; - _resultArray = null; - - // Room in current segment? - char[] curr = _currentSegment; - int max = curr.length - _currentSize; - if (max >= len) { - str.getChars(offset, offset+len, curr, _currentSize); - _currentSize += len; - } else { - // No room for all, need to copy part(s): - if (max > 0) { - str.getChars(offset, offset+max, curr, _currentSize); - len -= max; - offset += max; - } - /* And then allocate new segment; we are guaranteed to now - * have enough room in segment. - */ - expand(len); - str.getChars(offset, offset+len, _currentSegment, 0); - _currentSize = len; - } - } - - /* - ////////////////////////////////////////////// - // Raw access, for high-performance use: - ////////////////////////////////////////////// - */ - - public char[] getCurrentSegment() - { - /* Since the intention of the caller is to directly add stuff into - * buffers, we should NOT have anything in shared buffer... ie. may - * need to unshare contents. - */ - if (_inputStart >= 0) { - unshare(1); - } else { - char[] curr = _currentSegment; - if (curr == null) { - _currentSegment = findBuffer(0); - } else if (_currentSize >= curr.length) { - // Plus, we better have room for at least one more char - expand(1); - } - } - return _currentSegment; - } - - public char[] emptyAndGetCurrentSegment() - { - resetWithEmpty(); - char[] curr = _currentSegment; - if (curr == null) { - _currentSegment = curr = findBuffer(0); - } - return curr; - } - - public int getCurrentSegmentSize() { - return _currentSize; - } - - public void setCurrentLength(int len) { - _currentSize = len; - } - - public char[] finishCurrentSegment() - { - if (_segments == null) { - _segments = new ArrayList(); - } - _hasSegments = true; - _segments.add(_currentSegment); - int oldLen = _currentSegment.length; - _segmentSize += oldLen; - // Let's grow segments by 50% - int newLen = Math.min(oldLen + (oldLen >> 1), MAX_SEGMENT_LEN); - char[] curr = _charArray(newLen); - _currentSize = 0; - _currentSegment = curr; - return curr; - } - - /** - * Method called to expand size of the current segment, to accomodate for more contiguous content.Usually only used - * when parsing tokens like names. - * - * @return Undocumented. - */ - public char[] expandCurrentSegment() - { - char[] curr = _currentSegment; - // Let's grow by 50% - int len = curr.length; - // Must grow by at least 1 char, no matter what - int newLen = (len == MAX_SEGMENT_LEN) ? - (MAX_SEGMENT_LEN + 1) : Math.min(MAX_SEGMENT_LEN, len + (len >> 1)); - _currentSegment = _charArray(newLen); - System.arraycopy(curr, 0, _currentSegment, 0, len); - return _currentSegment; - } - - /* - ////////////////////////////////////////////// - // Standard methods: - ////////////////////////////////////////////// - */ - - /** - * Note: calling this method may not be as efficient as calling - * {@link #contentsAsString}, since it's not guaranteed that resulting - * String is cached. - */ - @Override - public String toString() { - return contentsAsString(); - } - - /* - ////////////////////////////////////////////// - // Internal methods: - ////////////////////////////////////////////// - */ - - /** - * Method called if/when we need to append content when we have been - * initialized to use shared buffer. - */ - private void unshare(int needExtra) - { - int sharedLen = _inputLen; - _inputLen = 0; - char[] inputBuf = _inputBuffer; - _inputBuffer = null; - int start = _inputStart; - _inputStart = -1; - - // Is buffer big enough, or do we need to reallocate? - int needed = sharedLen+needExtra; - if (_currentSegment == null || needed > _currentSegment.length) { - _currentSegment = findBuffer(needed); - } - if (sharedLen > 0) { - System.arraycopy(inputBuf, start, _currentSegment, 0, sharedLen); - } - _segmentSize = 0; - _currentSize = sharedLen; - } - - /** - * Method called when current segment is full, to allocate new - * segment. - */ - private void expand(int minNewSegmentSize) - { - // First, let's move current segment to segment list: - if (_segments == null) { - _segments = new ArrayList(); - } - char[] curr = _currentSegment; - _hasSegments = true; - _segments.add(curr); - _segmentSize += curr.length; - int oldLen = curr.length; - // Let's grow segments by 50% minimum - int sizeAddition = oldLen >> 1; - if (sizeAddition < minNewSegmentSize) { - sizeAddition = minNewSegmentSize; - } - curr = _charArray(Math.min(MAX_SEGMENT_LEN, oldLen + sizeAddition)); - _currentSize = 0; - _currentSegment = curr; - } - - private char[] buildResultArray() - { - if (_resultString != null) { // Can take a shortcut... - return _resultString.toCharArray(); - } - char[] result; - - // Do we use shared array? - if (_inputStart >= 0) { - if (_inputLen < 1) { - return NO_CHARS; - } - result = _charArray(_inputLen); - System.arraycopy(_inputBuffer, _inputStart, result, 0, - _inputLen); - } else { // nope - int size = size(); - if (size < 1) { - return NO_CHARS; - } - int offset = 0; - result = _charArray(size); - if (_segments != null) { - for (int i = 0, len = _segments.size(); i < len; ++i) { - char[] curr = (char[]) _segments.get(i); - int currLen = curr.length; - System.arraycopy(curr, 0, result, offset, currLen); - offset += currLen; - } - } - System.arraycopy(_currentSegment, 0, result, offset, _currentSize); - } - return result; - } - - private final char[] _charArray(int len) { - return new char[len]; - } -} diff --git a/src/org/codehaus/jackson/util/TokenBuffer.java b/src/org/codehaus/jackson/util/TokenBuffer.java deleted file mode 100644 index 1f1f2cfb18..0000000000 --- a/src/org/codehaus/jackson/util/TokenBuffer.java +++ /dev/null @@ -1,1243 +0,0 @@ -package org.codehaus.jackson.util; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.codehaus.jackson.*; -import org.codehaus.jackson.impl.JsonReadContext; -import org.codehaus.jackson.impl.JsonWriteContext; - -/** - * Utility class used for efficient storage of {@link JsonToken} - * sequences, needed for temporary buffering. - * Space efficient for different sequence lengths (especially so for smaller - * ones; but not significantly less efficient for larger), highly efficient - * for linear iteration and appending. Implemented as segmented/chunked - * linked list of tokens; only modifications are via appends. - * - * @since 1.5 - */ -public class TokenBuffer -/* Won't use JsonGeneratorBase, to minimize overhead for validity - * checking - */ - extends JsonGenerator -{ - final static int DEFAULT_FEATURES = JsonParser.Feature.collectDefaults(); - - /* - *********************************************** - * Configuration - *********************************************** - */ - - /** - * Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - */ - protected ObjectCodec _objectCodec; - - /** - * Bit flag composed of bits that indicate which - * {@link org.codehaus.jackson.JsonGenerator.Feature}s - * are enabled. - *

- * NOTE: most features have no effect on this class - */ - protected int _generatorFeatures; - - protected boolean _closed; - - /* - *********************************************** - * Token buffering state - *********************************************** - */ - - /** - * First segment, for contents this buffer has - */ - protected Segment _first; - - /** - * Last segment of this buffer, one that is used - * for appending more tokens - */ - protected Segment _last; - - /** - * Offset within last segment, - */ - protected int _appendOffset; - - /* - *********************************************** - * Output state - *********************************************** - */ - - protected JsonWriteContext _writeContext; - - /* - *********************************************** - * Life-cycle - *********************************************** - */ - - /** - * @param codec Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - */ - public TokenBuffer(ObjectCodec codec) - { - _objectCodec = codec; - _generatorFeatures = DEFAULT_FEATURES; - _writeContext = JsonWriteContext.createRootContext(); - // at first we have just one segment - _first = _last = new Segment(); - _appendOffset = 0; - } - - /** - * Method used to create a {@link JsonParser} that can read contents - * stored in this buffer. Will use default _objectCodec for - * object conversions. - *

- * Note: instances are not synchronized, that is, they are not thread-safe - * if there are concurrent appends to the underlying buffer. - * - * @return Parser that can be used for reading contents stored in this buffer - */ - public JsonParser asParser() - { - return asParser(_objectCodec); - } - - /** - * Method used to create a {@link JsonParser} that can read contents - * stored in this buffer. - *

- * Note: instances are not synchronized, that is, they are not thread-safe - * if there are concurrent appends to the underlying buffer. - * - * @param codec Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - * - * @return Parser that can be used for reading contents stored in this buffer - */ - public JsonParser asParser(ObjectCodec codec) - { - return new Parser(_first, codec); - } - - /** - * @param src Parser to use for accessing source information - * like location, configured codec - * @return Undocumented. - */ - public JsonParser asParser(JsonParser src) - { - Parser p = new Parser(_first, src.getCodec()); - p.setLocation(src.getTokenLocation()); - return p; - } - - /* - ***************************************************************** - * Other custom methods not needed for implementing interfaces - ***************************************************************** - */ - - /** - * Helper method that will write all contents of this buffer - * using given {@link JsonGenerator}. - *

- * Note: this method would be enough to implement - * JsonSerializer for TokenBuffer type; - * but we can not have upwards - * references (from core to mapper package); and as such we also - * can not take second argument. - * @param jgen Undocumented. - * @throws java.io.IOException Undocumented. - * @throws org.codehaus.jackson.JsonGenerationException Undocumented. - */ - public void serialize(JsonGenerator jgen) - throws IOException, JsonGenerationException - { - Segment segment = _first; - int ptr = -1; - - while (true) { - if (++ptr >= Segment.TOKENS_PER_SEGMENT) { - ptr = 0; - segment = segment.next(); - if (segment == null) break; - } - JsonToken t = segment.type(ptr); - if (t == null) break; - - // Note: copied from 'copyCurrentEvent'... - switch (t) { - case START_OBJECT: - jgen.writeStartObject(); - break; - case END_OBJECT: - jgen.writeEndObject(); - break; - case START_ARRAY: - jgen.writeStartArray(); - break; - case END_ARRAY: - jgen.writeEndArray(); - break; - case FIELD_NAME: - jgen.writeFieldName((String) segment.get(ptr)); - break; - case VALUE_STRING: - jgen.writeString((String) segment.get(ptr)); - break; - case VALUE_NUMBER_INT: - { - Number n = (Number) segment.get(ptr); - if (n instanceof BigInteger) { - jgen.writeNumber((BigInteger) n); - } else if (n instanceof Long) { - jgen.writeNumber(n.longValue()); - } else { - jgen.writeNumber(n.intValue()); - } - } - break; - case VALUE_NUMBER_FLOAT: - { - Number n = (Number) segment.get(ptr); - if (n instanceof BigDecimal) { - jgen.writeNumber((BigDecimal) n); - } else if (n instanceof Float) { - jgen.writeNumber(n.floatValue()); - } else { - jgen.writeNumber(n.doubleValue()); - } - } - break; - case VALUE_TRUE: - jgen.writeBoolean(true); - break; - case VALUE_FALSE: - jgen.writeBoolean(false); - break; - case VALUE_NULL: - jgen.writeNull(); - break; - case VALUE_EMBEDDED_OBJECT: - jgen.writeObject(segment.get(ptr)); - break; - default: - throw new RuntimeException("Internal error: should never end up through this code path"); - } - } - } - - @Override - public String toString() - { - // Let's print up to 100 first tokens... - final int MAX_COUNT = 100; - - StringBuilder sb = new StringBuilder(); - sb.append("[TokenBuffer: "); - JsonParser jp = asParser(); - int count = 0; - - while (true) { - JsonToken t; - try { - t = jp.nextToken(); - } catch (IOException ioe) { // should never occur - throw new IllegalStateException(ioe); - } - if (t == null) break; - if (count < MAX_COUNT) { - if (count > 0) { - sb.append(", "); - } - sb.append(t.toString()); - } - ++count; - } - - if (count >= MAX_COUNT) { - sb.append(" ... (truncated ").append(count-MAX_COUNT).append(" entries)"); - } - sb.append(']'); - return sb.toString(); - } - - /* - ***************************************************************** - * JsonGenerator implementation: configuration - ***************************************************************** - */ - - @Override - public JsonGenerator enable(Feature f) { - _generatorFeatures |= f.getMask(); - return this; - } - - @Override - public JsonGenerator disable(Feature f) { - _generatorFeatures &= ~f.getMask(); - return this; - } - - //public JsonGenerator configure(Feature f, boolean state) { } - - @Override - public boolean isEnabled(Feature f) { - return (_generatorFeatures & f.getMask()) != 0; - } - - public JsonGenerator useDefaultPrettyPrinter() { - // No-op: we don't indent - return this; - } - - public JsonGenerator setCodec(ObjectCodec oc) { - _objectCodec = oc; - return this; - } - - public ObjectCodec getCodec() { return _objectCodec; } - - public final JsonWriteContext getOutputContext() { return _writeContext; } - - /* - ***************************************************************** - * JsonGenerator implementation: low-level output handling - ***************************************************************** - */ - - public void flush() throws IOException { /* NOP */ } - - public void close() throws IOException { - _closed = true; - } - - public boolean isClosed() { return _closed; } - - /* - ***************************************************************** - * JsonGenerator implementation: write methods, structural - ***************************************************************** - */ - - @Override - public final void writeStartArray() - throws IOException, JsonGenerationException - { - _append(JsonToken.START_ARRAY); - _writeContext = _writeContext.createChildArrayContext(); - } - - @Override - public final void writeEndArray() - throws IOException, JsonGenerationException - { - _append(JsonToken.END_ARRAY); - // Let's allow unbalanced tho... i.e. not run out of root level, ever - JsonWriteContext c = _writeContext.getParent(); - if (c != null) { - _writeContext = c; - } - } - - @Override - public final void writeStartObject() - throws IOException, JsonGenerationException - { - _append(JsonToken.START_OBJECT); - _writeContext = _writeContext.createChildObjectContext(); - } - - public final void writeEndObject() - throws IOException, JsonGenerationException - { - _append(JsonToken.END_OBJECT); - // Let's allow unbalanced tho... i.e. not run out of root level, ever - JsonWriteContext c = _writeContext.getParent(); - if (c != null) { - _writeContext = c; - } - } - - public final void writeFieldName(String name) - throws IOException, JsonGenerationException - { - _append(JsonToken.FIELD_NAME, name); - _writeContext.writeFieldName(name); - } - - /* - ***************************************************************** - * JsonGenerator implementation: write methods, textual - ***************************************************************** - */ - - @Override - public void writeString(String text) throws IOException,JsonGenerationException { - if (text == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_STRING, text); - } - } - - @Override - public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException { - writeString(new String(text, offset, len)); - } - - @Override - public void writeRaw(String text) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(char c) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(String text) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(String text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(char[] text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - /* - ***************************************************************** - * JsonGenerator implementation: write methods, primitive types - ***************************************************************** - */ - - @Override - public void writeNumber(int i) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_INT, Integer.valueOf(i)); - } - - @Override - public void writeNumber(long l) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_INT, Long.valueOf(l)); - } - - @Override - public void writeNumber(double d) throws IOException,JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_FLOAT, Double.valueOf(d)); - } - - @Override - public void writeNumber(float f) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_FLOAT, Float.valueOf(f)); - } - - @Override - public void writeNumber(BigDecimal dec) throws IOException,JsonGenerationException { - if (dec == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_NUMBER_FLOAT, dec); - } - } - - @Override - public void writeNumber(BigInteger v) throws IOException, JsonGenerationException { - if (v == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_NUMBER_INT, v); - } - } - - @Override - public void writeNumber(String encodedValue) throws IOException, JsonGenerationException { - /* Hmmh... let's actually support this as regular String value write: - * should work since there is no quoting when buffering - */ - writeString(encodedValue); - } - - @Override - public void writeBoolean(boolean state) throws IOException,JsonGenerationException { - _append(state ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE); - } - - @Override - public void writeNull() throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NULL); - } - - /* - ***************************************************************** - * JsonGenerator implementation: write methods for POJOs/trees - ***************************************************************** - */ - - public void writeObject(Object value) - throws IOException, JsonProcessingException - { - // embedded means that no conversions should be done... - _append(JsonToken.VALUE_EMBEDDED_OBJECT, value); - } - - public void writeTree(JsonNode rootNode) - throws IOException, JsonProcessingException - { - /* 31-Dec-2009, tatu: no need to convert trees either is there? - * (note: may need to re-evaluate at some point) - */ - _append(JsonToken.VALUE_EMBEDDED_OBJECT, rootNode); - } - - /* - ***************************************************************** - * JsonGenerator implementation; binary - ***************************************************************** - */ - - @Override - public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) - throws IOException, JsonGenerationException - { - /* 31-Dec-2009, tatu: can do this using multiple alternatives; but for - * now, let's try to limit number of conversions. - * The only (?) tricky thing is that of whether to preserve variant, - * seems pointless, so let's not worry about it unless there's some - * compelling reason to. - */ - byte[] copy = new byte[len]; - System.arraycopy(data, offset, copy, 0, len); - writeObject(copy); - } - - /* - ***************************************************************** - * JsonGenerator implementation; pass-through copy - ***************************************************************** - */ - - @Override - public void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException - { - switch (jp.getCurrentToken()) { - case START_OBJECT: - writeStartObject(); - break; - case END_OBJECT: - writeEndObject(); - break; - case START_ARRAY: - writeStartArray(); - break; - case END_ARRAY: - writeEndArray(); - break; - case FIELD_NAME: - writeFieldName(jp.getCurrentName()); - break; - case VALUE_STRING: - writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength()); - break; - case VALUE_NUMBER_INT: - switch (jp.getNumberType()) { - case INT: - writeNumber(jp.getIntValue()); - break; - case BIG_INTEGER: - writeNumber(jp.getBigIntegerValue()); - break; - default: - writeNumber(jp.getLongValue()); - } - break; - case VALUE_NUMBER_FLOAT: - switch (jp.getNumberType()) { - case BIG_DECIMAL: - writeNumber(jp.getDecimalValue()); - break; - case FLOAT: - writeNumber(jp.getFloatValue()); - break; - default: - writeNumber(jp.getDoubleValue()); - } - break; - case VALUE_TRUE: - writeBoolean(true); - break; - case VALUE_FALSE: - writeBoolean(false); - break; - case VALUE_NULL: - writeNull(); - break; - case VALUE_EMBEDDED_OBJECT: - writeObject(jp.getEmbeddedObject()); - break; - default: - throw new RuntimeException("Internal error: should never end up through this code path"); - } - } - - @Override - public void copyCurrentStructure(JsonParser jp) throws IOException, JsonProcessingException { - JsonToken t = jp.getCurrentToken(); - - // Let's handle field-name separately first - if (t == JsonToken.FIELD_NAME) { - writeFieldName(jp.getCurrentName()); - t = jp.nextToken(); - // fall-through to copy the associated value - } - - switch (t) { - case START_ARRAY: - writeStartArray(); - while (jp.nextToken() != JsonToken.END_ARRAY) { - copyCurrentStructure(jp); - } - writeEndArray(); - break; - case START_OBJECT: - writeStartObject(); - while (jp.nextToken() != JsonToken.END_OBJECT) { - copyCurrentStructure(jp); - } - writeEndObject(); - break; - default: // others are simple: - copyCurrentEvent(jp); - } - } - - /* - ***************************************************************** - * Internal methods - ***************************************************************** - */ - protected final void _append(JsonToken type) { - Segment next = _last.append(_appendOffset, type); - if (next == null) { - ++_appendOffset; - } else { - _last = next; - _appendOffset = 1; // since we added first at 0 - } - } - - protected final void _append(JsonToken type, Object value) { - Segment next = _last.append(_appendOffset, type, value); - if (next == null) { - ++_appendOffset; - } else { - _last = next; - _appendOffset = 1; - } - } - - protected void _reportUnsupportedOperation() { - throw new UnsupportedOperationException("Called operation not supported for TokenBuffer"); - } - - /* - ***************************************************************** - * Supporting classes - ***************************************************************** - */ - - protected final static class Parser - extends JsonParser - { - protected ObjectCodec _codec; - - /* - //////////////////////////////////////////////////// - // Parsing state - //////////////////////////////////////////////////// - */ - - /** - * Currently active segment - */ - protected Segment _segment; - - /** - * Pointer to current token within current segment - */ - protected int _segmentPtr; - - /** - * Information about parser context, context in which - * the next token is to be parsed (root, array, object). - */ - protected JsonReadContext _parsingContext; - - protected boolean _closed; - - protected transient ByteArrayBuilder _byteBuilder; - - protected JsonLocation _location = null; - - /* - //////////////////////////////////////////////////// - // Construction, init - //////////////////////////////////////////////////// - */ - - public Parser(Segment firstSeg, ObjectCodec codec) { - _segment = firstSeg; - _segmentPtr = -1; // not yet read - _codec = codec; - _parsingContext = JsonReadContext.createRootContext(-1, -1); - } - - public void setLocation(JsonLocation l) { - _location = l; - } - - @Override - public ObjectCodec getCodec() { return _codec; } - - @Override - public void setCodec(ObjectCodec c) { _codec = c; } - - /* - //////////////////////////////////////////////////// - // Closeable implementation - //////////////////////////////////////////////////// - */ - - @Override - public void close() throws IOException { - if (!_closed) { - _closed = true; - } - } - - /* - //////////////////////////////////////////////////// - // Public API, traversal - //////////////////////////////////////////////////// - */ - - @Override - public JsonToken nextToken() throws IOException, JsonParseException - { - // If we are closed, nothing more to do - if (_closed || (_segment == null)) return null; - - // Ok, then: any more tokens? - if (++_segmentPtr >= Segment.TOKENS_PER_SEGMENT) { - _segmentPtr = 0; - _segment = _segment.next(); - if (_segment == null) { - return null; - } - } - _currToken = _segment.type(_segmentPtr); - // Field name? Need to update context - if (_currToken == JsonToken.FIELD_NAME) { - _parsingContext.setCurrentName((String) _currentObject()); - } else if (_currToken == JsonToken.START_OBJECT) { - _parsingContext = _parsingContext.createChildObjectContext(-1, -1); - } else if (_currToken == JsonToken.START_ARRAY) { - _parsingContext = _parsingContext.createChildArrayContext(-1, -1); - } else if (_currToken == JsonToken.END_OBJECT - || _currToken == JsonToken.END_ARRAY) { - // Closing JSON Object/Array? Close matching context - _parsingContext = _parsingContext.getParent(); - // but allow unbalanced cases too (more close markers) - if (_parsingContext == null) { - _parsingContext = JsonReadContext.createRootContext(-1, -1); - } - } - return _currToken; - } - - @Override - public JsonParser skipChildren() throws IOException, JsonParseException - { - if (_currToken != JsonToken.START_OBJECT && _currToken != JsonToken.START_ARRAY) { - return this; - } - int open = 1; - - /* Since proper matching of start/end markers is handled - * by nextToken(), we'll just count nesting levels here - */ - while (true) { - JsonToken t = nextToken(); - if (t == null) { - // error for most parsers, but ok here - return this; - } - switch (t) { - case START_OBJECT: - case START_ARRAY: - ++open; - break; - case END_OBJECT: - case END_ARRAY: - if (--open == 0) { - return this; - } - break; - } - } - } - - @Override - public boolean isClosed() { return _closed; } - - /* - //////////////////////////////////////////////////// - // Public API, token accessors - //////////////////////////////////////////////////// - */ - - @Override - public JsonStreamContext getParsingContext() { return _parsingContext; } - - @Override - public JsonLocation getTokenLocation() { return getCurrentLocation(); } - - @Override - public JsonLocation getCurrentLocation() { - return (_location == null) ? JsonLocation.NA : _location; - } - - @Override - public String getCurrentName() { return _parsingContext.getCurrentName(); } - - /* - //////////////////////////////////////////////////// - // Public API, access to token information, text - //////////////////////////////////////////////////// - */ - - @Override - public String getText() - { - if (_currToken != null) { // null only before/after document - switch (_currToken) { - case FIELD_NAME: - case VALUE_STRING: - return (String) _currentObject(); - // fall through - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - Object ob = _currentObject(); - return (ob == null) ? null : ob.toString(); - default: - return _currToken.asString(); - } - } - return null; - } - - @Override - public char[] getTextCharacters() { - String str = getText(); - return (str == null) ? null : str.toCharArray(); - } - - @Override - public int getTextLength() { - String str = getText(); - return (str == null) ? 0 : str.length(); - } - - @Override - public int getTextOffset() { return 0; } - - /* - //////////////////////////////////////////////////// - // Public API, access to token information, numeric - //////////////////////////////////////////////////// - */ - - @Override - public BigInteger getBigIntegerValue() throws IOException, JsonParseException - { - Number n = getNumberValue(); - if (n instanceof BigInteger) { - return (BigInteger) n; - } - switch (getNumberType()) { - case BIG_DECIMAL: - return ((BigDecimal) n).toBigInteger(); - } - // int/long is simple, but let's also just truncate float/double: - return BigInteger.valueOf(n.longValue()); - } - - @Override - public BigDecimal getDecimalValue() throws IOException, JsonParseException - { - Number n = getNumberValue(); - if (n instanceof BigDecimal) { - return (BigDecimal) n; - } - switch (getNumberType()) { - case INT: - case LONG: - return BigDecimal.valueOf(n.longValue()); - case BIG_INTEGER: - return new BigDecimal((BigInteger) n); - } - // float or double - return BigDecimal.valueOf(n.doubleValue()); - } - - @Override - public double getDoubleValue() throws IOException, JsonParseException { - return getNumberValue().doubleValue(); - } - - @Override - public float getFloatValue() throws IOException, JsonParseException { - return getNumberValue().floatValue(); - } - - @Override - public int getIntValue() throws IOException, JsonParseException { - return getNumberValue().intValue(); - } - - @Override - public long getLongValue() throws IOException, JsonParseException { - return getNumberValue().longValue(); - } - - @Override - public NumberType getNumberType() throws IOException, JsonParseException - { - Number n = getNumberValue(); - if (n instanceof Integer) return NumberType.INT; - if (n instanceof Long) return NumberType.LONG; - if (n instanceof Double) return NumberType.DOUBLE; - if (n instanceof BigDecimal) return NumberType.BIG_DECIMAL; - if (n instanceof Float) return NumberType.FLOAT; - if (n instanceof BigInteger) return NumberType.BIG_INTEGER; - return null; - } - - @Override - public final Number getNumberValue() throws IOException, JsonParseException { - _checkIsNumber(); - return (Number) _currentObject(); - } - - /* - //////////////////////////////////////////////////// - // Public API, access to token information, other - //////////////////////////////////////////////////// - */ - - private final static int INT_SPACE = 0x0020; - - public Object getEmbeddedObject() - { - if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) { - return _currentObject(); - } - return null; - } - - @Override - public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException - { - // First: maybe we some special types? - if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) { - // Embedded byte array would work nicely... - Object ob = _currentObject(); - if (ob instanceof byte[]) { - return (byte[]) ob; - } - // fall through to error case - } - if (_currToken != JsonToken.VALUE_STRING) { - throw _constructError("Current token ("+_currToken+") not VALUE_STRING (or VALUE_EMBEDDED_OBJECT with byte[]), can not access as binary"); - } - final String str = getText(); - if (str == null) { - return null; - } - ByteArrayBuilder builder = _byteBuilder; - if (builder == null) { - _byteBuilder = builder = new ByteArrayBuilder(100); - } - _decodeBase64(str, builder, b64variant); - return builder.toByteArray(); - } - - /* - //////////////////////////////////////////////////// - // Internal methods - //////////////////////////////////////////////////// - */ - - protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant) - throws IOException, JsonParseException - { - int ptr = 0; - int len = str.length(); - - main_loop: - while (ptr < len) { - // first, we'll skip preceding white space, if any - char ch; - do { - ch = str.charAt(ptr++); - if (ptr >= len) { - break main_loop; - } - } while (ch <= INT_SPACE); - int bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - _reportInvalidBase64(b64variant, ch, 0, null); - } - int decodedData = bits; - // then second base64 char; can't get padding yet, nor ws - if (ptr >= len) { - _reportBase64EOF(); - } - ch = str.charAt(ptr++); - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - _reportInvalidBase64(b64variant, ch, 1, null); - } - decodedData = (decodedData << 6) | bits; - // third base64 char; can be padding, but not ws - if (ptr >= len) { - _reportBase64EOF(); - } - ch = str.charAt(ptr++); - bits = b64variant.decodeBase64Char(ch); - - // First branch: can get padding (-> 1 byte) - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - _reportInvalidBase64(b64variant, ch, 2, null); - } - // Ok, must get padding - if (ptr >= len) { - _reportBase64EOF(); - } - ch = str.charAt(ptr++); - if (!b64variant.usesPaddingChar(ch)) { - _reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'"); - } - // Got 12 bits, only need 8, need to shift - decodedData >>= 4; - builder.append(decodedData); - continue; - } - // Nope, 2 or 3 bytes - decodedData = (decodedData << 6) | bits; - // fourth and last base64 char; can be padding, but not ws - if (ptr >= len) { - _reportBase64EOF(); - } - ch = str.charAt(ptr++); - bits = b64variant.decodeBase64Char(ch); - if (bits < 0) { - if (bits != Base64Variant.BASE64_VALUE_PADDING) { - _reportInvalidBase64(b64variant, ch, 3, null); - } - decodedData >>= 2; - builder.appendTwoBytes(decodedData); - } else { - // otherwise, our triple is now complete - decodedData = (decodedData << 6) | bits; - builder.appendThreeBytes(decodedData); - } - } - } - - protected final Object _currentObject() { - return _segment.get(_segmentPtr); - } - - protected void _checkIsNumber() throws JsonParseException - { - if (_currToken == null || !_currToken.isNumeric()) { - throw _constructError("Current token ("+_currToken+") not numeric, can not use numeric value accessors"); - } - } - - /** - * @param b64variant Undocumented. - * @param ch Undocumented. - * @param bindex Relative index within base64 character unit; between 0 - * and 3 (as unit has exactly 4 characters) - * @param msg Undocumented. - * @throws org.codehaus.jackson.JsonParseException Undocumented. - */ - protected void _reportInvalidBase64(Base64Variant b64variant, char ch, int bindex, String msg) - throws JsonParseException - { - String base; - if (ch <= INT_SPACE) { - base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units"; - } else if (b64variant.usesPaddingChar(ch)) { - base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character"; - } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) { - // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level) - base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } else { - base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content"; - } - if (msg != null) { - base = base + ": " + msg; - } - throw _constructError(base); - } - - protected void _reportBase64EOF() throws JsonParseException { - throw _constructError("Unexpected end-of-String in base64 content"); - } - } - - /** - * Individual segment of TokenBuffer that can store up to 16 tokens - * (limited by 4 bits per token type marker requirement). - * Current implementation uses fixed length array; could alternatively - * use 16 distinct fields and switch statement (slightly more efficient - * storage, slightly slower access) - */ - protected final static class Segment - { - public final static int TOKENS_PER_SEGMENT = 16; - - /** - * Static array used for fast conversion between token markers and - * matching {@link JsonToken} instances - */ - private final static JsonToken[] TOKEN_TYPES_BY_INDEX; - static { - // ... here we know that there are <= 16 values in JsonToken enum - TOKEN_TYPES_BY_INDEX = new JsonToken[16]; - JsonToken[] t = JsonToken.values(); - System.arraycopy(t, 1, TOKEN_TYPES_BY_INDEX, 1, Math.min(15, t.length - 1)); - } - - // // // Linking - - protected Segment _next; - - // // // State - - /** - * Bit field used to store types of buffered tokens; 4 bits per token. - * Value 0 is reserved for "not in use" - */ - protected long _tokenTypes; - - - // Actual tokens - - protected final Object[] _tokens = new Object[TOKENS_PER_SEGMENT]; - - public Segment() { } - - // // // Accessors - - public JsonToken type(int index) - { - long l = _tokenTypes; - if (index > 0) { - l >>= (index << 2); - } - int ix = ((int) l) & 0xF; - return TOKEN_TYPES_BY_INDEX[ix]; - } - - public Object get(int index) { - return _tokens[index]; - } - - public Segment next() { return _next; } - - // // // Mutators - - public Segment append(int index, JsonToken tokenType) - { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType); - return null; - } - _next = new Segment(); - _next.set(0, tokenType); - return _next; - } - - public Segment append(int index, JsonToken tokenType, Object value) - { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType, value); - return null; - } - _next = new Segment(); - _next.set(0, tokenType, value); - return _next; - } - - public void set(int index, JsonToken tokenType) - { - long typeCode = tokenType.ordinal(); - /* Assumption here is that there are no overwrites, just appends; - * and so no masking is needed - */ - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - } - - public void set(int index, JsonToken tokenType, Object value) - { - _tokens[index] = value; - long typeCode = tokenType.ordinal(); - /* Assumption here is that there are no overwrites, just appends; - * and so no masking is needed - */ - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - } - } -} diff --git a/test/gov/nasa/worldwind/data/RasterServerConfigurationTest.java b/test/gov/nasa/worldwind/data/RasterServerConfigurationTest.java index e81db2dabd..0f68f8e13d 100644 --- a/test/gov/nasa/worldwind/data/RasterServerConfigurationTest.java +++ b/test/gov/nasa/worldwind/data/RasterServerConfigurationTest.java @@ -29,16 +29,12 @@ package gov.nasa.worldwind.data; import gov.nasa.worldwind.geom.Sector; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class RasterServerConfigurationTest { @Test @@ -55,64 +51,64 @@ public void testParsing001() e.printStackTrace(); } - assertNotNull("Version is null", config.getVersion()); - assertEquals("Incorrect version number", "1.0", config.getVersion()); + assertNotNull(config.getVersion(), "Version is null"); + assertEquals("1.0", config.getVersion(), "Incorrect version number"); Sector sector = config.getSector(); - assertNotNull("Configuration sector is null", sector); - assertEquals("Configuration sector min latitude is incorrect", -50.0, sector.getMinLatitude().degrees, 0.0); - assertEquals("Configuration sector max latitude is incorrect", -47.0, sector.getMaxLatitude().degrees, 0.0); - assertEquals("Configuration sector min longitude is incorrect", 178.0, sector.getMinLongitude().degrees, 0.0); - assertEquals("Configuration sector max longitude is incorrect", 180.0, sector.getMaxLongitude().degrees, 0.0); + assertNotNull(sector, "Configuration sector is null"); + assertEquals(-50.0, sector.getMinLatitude().degrees, 0.0, "Configuration sector min latitude is incorrect"); + assertEquals(-47.0, sector.getMaxLatitude().degrees, 0.0, "Configuration sector max latitude is incorrect"); + assertEquals(178.0, sector.getMinLongitude().degrees, 0.0, "Configuration sector min longitude is incorrect"); + assertEquals(180.0, sector.getMaxLongitude().degrees, 0.0, "Configuration sector max longitude is incorrect"); Map props = config.getProperties(); - assertNotNull("Properties table is null", props); - assertEquals("Properties table length is incorrect", 3, props.size()); + assertNotNull(props, "Properties table is null"); + assertEquals(3, props.size(), "Properties table length is incorrect"); String prop = props.get("gov.nasa.worldwind.avkey.DisplayName"); - assertNotNull("Property 1 is missing", prop); - assertEquals("Property 1 is incorrect", "Desktop DTEDfromSTL 30m DTED2 Elevations", prop); + assertNotNull(prop, "Property 1 is missing"); + assertEquals("Desktop DTEDfromSTL 30m DTED2 Elevations", prop, "Property 1 is incorrect"); prop = props.get("gov.nasa.worldwind.avkey.DatasetNameKey"); - assertNotNull("Property 2 is missing", prop); - assertEquals("Property 2 is incorrect", "Desktop DTEDfromSTL 30m DTED2 Elevations", prop); + assertNotNull(prop, "Property 2 is missing"); + assertEquals("Desktop DTEDfromSTL 30m DTED2 Elevations", prop, "Property 2 is incorrect"); prop = props.get("gov.nasa.worldwind.avkey.DataCacheNameKey"); - assertNotNull("Property 3 is missing", prop); - assertEquals("Property 3 is incorrect", "Desktop DTEDfromSTL 30m DTED2 Elevations", prop); + assertNotNull(prop, "Property 3 is missing"); + assertEquals("Desktop DTEDfromSTL 30m DTED2 Elevations", prop, "Property 3 is incorrect"); List sources = config.getSources(); - assertNotNull("Configuration sources is null", sources); - assertEquals("Configuration sources length is incorrect", 2, sources.size()); + assertNotNull(sources, "Configuration sources is null"); + assertEquals(2, sources.size(), "Configuration sources length is incorrect"); RasterServerConfiguration.Source source = sources.get(0); - assertNotNull("Source 1 is null", source); + assertNotNull(source, "Source 1 is null"); String path = source.getPath(); - assertNotNull("Source path 1 is null", path); - assertEquals("Source path 1 is incorrect", "/Users/tag/Desktop/DTEDfromSTL/30m DTED2/s48 e179.dt2", path); + assertNotNull(path, "Source path 1 is null"); + assertEquals("/Users/tag/Desktop/DTEDfromSTL/30m DTED2/s48 e179.dt2", path, "Source path 1 is incorrect"); String type = source.getType(); - assertNotNull("Source type 1 is null", type); - assertEquals("Source type 1 is incorrect", "file", type); + assertNotNull(type, "Source type 1 is null"); + assertEquals("file", type, "Source type 1 is incorrect"); sector = source.getSector(); - assertNotNull("Source sector 1 is null", sector); - assertEquals("Source sector 1 min latitude is incorrect", -48.0, sector.getMinLatitude().degrees, 0.0); - assertEquals("Source sector 1 max latitude is incorrect", -47.0, sector.getMaxLatitude().degrees, 0.0); - assertEquals("Source sector 1 min longitude is incorrect", 179.0, sector.getMinLongitude().degrees, 0.0); - assertEquals("Source sector 1 max longitude is incorrect", 180.0, sector.getMaxLongitude().degrees, 0.0); + assertNotNull(sector, "Source sector 1 is null"); + assertEquals(-48.0, sector.getMinLatitude().degrees, 0.0, "Source sector 1 min latitude is incorrect"); + assertEquals(-47.0, sector.getMaxLatitude().degrees, 0.0, "Source sector 1 max latitude is incorrect"); + assertEquals(179.0, sector.getMinLongitude().degrees, 0.0, "Source sector 1 min longitude is incorrect"); + assertEquals(180.0, sector.getMaxLongitude().degrees, 0.0, "Source sector 1 max longitude is incorrect"); source = sources.get(1); - assertNotNull("Source 2 is null", source); + assertNotNull(source, "Source 2 is null"); path = source.getPath(); - assertNotNull("Source path 2 is null", path); - assertEquals("Source path 2 is incorrect", "/Users/tag/Desktop/DTEDfromSTL/30m DTED2/s50 e178.dt2", path); + assertNotNull(path, "Source path 2 is null"); + assertEquals("/Users/tag/Desktop/DTEDfromSTL/30m DTED2/s50 e178.dt2", path, "Source path 2 is incorrect"); type = source.getType(); - assertNotNull("Source type 2 is null", type); - assertEquals("Source type 2 is incorrect", "file", type); + assertNotNull(type, "Source type 2 is null"); + assertEquals("file", type, "Source type 2 is incorrect"); sector = source.getSector(); - assertNotNull("Source sector 2 is null", sector); - assertEquals("Source sector 2 min latitude is incorrect", -50.0, sector.getMinLatitude().degrees, 0.0); - assertEquals("Source sector 2 max latitude is incorrect", -49.0, sector.getMaxLatitude().degrees, 0.0); - assertEquals("Source sector 2 min longitude is incorrect", 178.0, sector.getMinLongitude().degrees, 0.0); - assertEquals("Source sector 2 max longitude is incorrect", 179.0, sector.getMaxLongitude().degrees, 0.0); + assertNotNull(sector, "Source sector 2 is null"); + assertEquals(-50.0, sector.getMinLatitude().degrees, 0.0, "Source sector 2 min latitude is incorrect"); + assertEquals(-49.0, sector.getMaxLatitude().degrees, 0.0, "Source sector 2 max latitude is incorrect"); + assertEquals(178.0, sector.getMinLongitude().degrees, 0.0, "Source sector 2 min longitude is incorrect"); + assertEquals(179.0, sector.getMaxLongitude().degrees, 0.0, "Source sector 2 max longitude is incorrect"); } } diff --git a/test/gov/nasa/worldwind/formats/georss/GeoRSSParserTest.java b/test/gov/nasa/worldwind/formats/georss/GeoRSSParserTest.java index fc7a05b310..ffa04fa24a 100644 --- a/test/gov/nasa/worldwind/formats/georss/GeoRSSParserTest.java +++ b/test/gov/nasa/worldwind/formats/georss/GeoRSSParserTest.java @@ -29,14 +29,11 @@ import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.render.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; @SuppressWarnings("deprecation") -@RunWith(JUnit4.class) public class GeoRSSParserTest { ////////////////////////////////////////////////////////// // GeoRSS-Simple Parsing Tests @@ -49,7 +46,7 @@ public void testSimple_Point() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // is not translated to any renderable shape. - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -60,7 +57,7 @@ public void testSimple_PointWithElevation() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // is not translated to any renderable shape. - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -70,19 +67,19 @@ public void testSimple_Line() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Path. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); Path shape = (Path) shapes.get(0); java.util.List positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2), ""); } @Test @@ -93,19 +90,19 @@ public void testSimple_LineWithElevation() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Path. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); Path shape = (Path) shapes.get(0); java.util.List positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 313.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 313.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 313.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 313.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 313.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 313.0), positions.get(2), ""); } @Test @@ -115,20 +112,20 @@ public void testSimple_Polygon() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ SurfacePolygon when no elevation is specified. - assertTrue("", shapes.get(0) instanceof SurfacePolygon); + assertTrue(shapes.get(0) instanceof SurfacePolygon, ""); SurfacePolygon shape = (SurfacePolygon) shapes.get(0); java.util.List positions = (java.util.List) shape.getLocations(); - assertNotNull("", positions); - assertEquals("", 4, positions.size()); - assertEquals("", LatLon.fromDegrees(45.256, -110.45), positions.get(0)); - assertEquals("", LatLon.fromDegrees(46.46, -109.48), positions.get(1)); - assertEquals("", LatLon.fromDegrees(43.84, -109.86), positions.get(2)); - assertEquals("", LatLon.fromDegrees(45.256, -110.45), positions.get(3)); + assertNotNull(positions, ""); + assertEquals(4, positions.size(), ""); + assertEquals(LatLon.fromDegrees(45.256, -110.45), positions.get(0), ""); + assertEquals(LatLon.fromDegrees(46.46, -109.48), positions.get(1), ""); + assertEquals(LatLon.fromDegrees(43.84, -109.86), positions.get(2), ""); + assertEquals(LatLon.fromDegrees(45.256, -110.45), positions.get(3), ""); } @Test @@ -139,20 +136,20 @@ public void testSimple_PolygonWithElevation() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Path when an elevation is specified. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); Path shape = (Path) shapes.get(0); java.util.List positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 4, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 313.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 313.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 313.0), positions.get(2)); - assertEquals("", Position.fromDegrees(45.256, -110.45, 313.0), positions.get(3)); + assertNotNull(positions, ""); + assertEquals(4, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 313.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 313.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 313.0), positions.get(2), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 313.0), positions.get(3), ""); } @Test @@ -162,20 +159,20 @@ public void testSimple_Box() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ SurfaceSector when no elevation is specified. - assertTrue("", shapes.get(0) instanceof SurfaceSector); + assertTrue(shapes.get(0) instanceof SurfaceSector, ""); SurfaceSector shape = (SurfaceSector) shapes.get(0); java.util.List positions = shape.getSector().asList(); - assertNotNull("", positions); - assertEquals("", 4, positions.size()); - assertEquals("", LatLon.fromDegrees(42.943, -71.032), positions.get(0)); - assertEquals("", LatLon.fromDegrees(42.943, -69.856), positions.get(1)); - assertEquals("", LatLon.fromDegrees(43.039, -69.856), positions.get(2)); - assertEquals("", LatLon.fromDegrees(43.039, -71.032), positions.get(3)); + assertNotNull(positions, ""); + assertEquals(4, positions.size(), ""); + assertEquals(LatLon.fromDegrees(42.943, -71.032), positions.get(0), ""); + assertEquals(LatLon.fromDegrees(42.943, -69.856), positions.get(1), ""); + assertEquals(LatLon.fromDegrees(43.039, -69.856), positions.get(2), ""); + assertEquals(LatLon.fromDegrees(43.039, -71.032), positions.get(3), ""); } @Test @@ -186,19 +183,19 @@ public void testSimple_BoxWithElevation() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Quadrilateral when an elevation is specified. - assertTrue("", shapes.get(0) instanceof Quadrilateral); + assertTrue(shapes.get(0) instanceof Quadrilateral, ""); Quadrilateral shape = (Quadrilateral) shapes.get(0); LatLon[] positions = shape.getCorners(); - assertNotNull("", positions); - assertEquals("", 2, positions.length); - assertEquals("", LatLon.fromDegrees(42.943, -71.032), positions[0]); - assertEquals("", LatLon.fromDegrees(43.039, -69.856), positions[1]); - assertEquals("", 313.0, shape.getElevation(), 0.0); + assertNotNull(positions, ""); + assertEquals(2, positions.length, ""); + assertEquals(LatLon.fromDegrees(42.943, -71.032), positions[0], ""); + assertEquals(LatLon.fromDegrees(43.039, -69.856), positions[1], ""); + assertEquals(313.0, shape.getElevation(), 0.0, ""); } ////////////////////////////////////////////////////////// @@ -215,7 +212,7 @@ public void testGML_Point() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // is not translated to any renderable shape. - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -231,19 +228,19 @@ public void testGML_Line() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Path. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); Path shape = (Path) shapes.get(0); java.util.List positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2), ""); } @Test @@ -263,20 +260,20 @@ public void testGML_Polygon() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ SurfacePolygon. - assertTrue("", shapes.get(0) instanceof SurfacePolygon); + assertTrue(shapes.get(0) instanceof SurfacePolygon, ""); SurfacePolygon shape = (SurfacePolygon) shapes.get(0); java.util.List positions = (java.util.List) shape.getLocations(); - assertNotNull("", positions); - assertEquals("", 4, positions.size()); - assertEquals("", LatLon.fromDegrees(45.256, -110.45), positions.get(0)); - assertEquals("", LatLon.fromDegrees(46.46, -109.48), positions.get(1)); - assertEquals("", LatLon.fromDegrees(43.84, -109.86), positions.get(2)); - assertEquals("", LatLon.fromDegrees(45.256, -110.45), positions.get(3)); + assertNotNull(positions, ""); + assertEquals(4, positions.size(), ""); + assertEquals(LatLon.fromDegrees(45.256, -110.45), positions.get(0), ""); + assertEquals(LatLon.fromDegrees(46.46, -109.48), positions.get(1), ""); + assertEquals(LatLon.fromDegrees(43.84, -109.86), positions.get(2), ""); + assertEquals(LatLon.fromDegrees(45.256, -110.45), positions.get(3), ""); } @Test @@ -291,20 +288,20 @@ public void testGML_Box() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ SurfaceSector when no elevation is specified. - assertTrue("", shapes.get(0) instanceof SurfaceSector); + assertTrue(shapes.get(0) instanceof SurfaceSector, ""); SurfaceSector shape = (SurfaceSector) shapes.get(0); java.util.List positions = shape.getSector().asList(); - assertNotNull("", positions); - assertEquals("", 4, positions.size()); - assertEquals("", LatLon.fromDegrees(42.943, -71.032), positions.get(0)); - assertEquals("", LatLon.fromDegrees(42.943, -69.856), positions.get(1)); - assertEquals("", LatLon.fromDegrees(43.039, -69.856), positions.get(2)); - assertEquals("", LatLon.fromDegrees(43.039, -71.032), positions.get(3)); + assertNotNull(positions, ""); + assertEquals(4, positions.size(), ""); + assertEquals(LatLon.fromDegrees(42.943, -71.032), positions.get(0), ""); + assertEquals(LatLon.fromDegrees(42.943, -69.856), positions.get(1), ""); + assertEquals(LatLon.fromDegrees(43.039, -69.856), positions.get(2), ""); + assertEquals(LatLon.fromDegrees(43.039, -71.032), positions.get(3), ""); } ////////////////////////////////////////////////////////// @@ -316,7 +313,7 @@ public void testSimple_PointNotEnoughPairs() { ""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -325,7 +322,7 @@ public void testSimple_LineNotEnoughPairs() { "45.256 -110.45"); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -334,7 +331,7 @@ public void testSimple_PolygonNotEnoughPairs() { "45.256 -110.45 46.46 -109.48 43.84 -109.86"); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -343,7 +340,7 @@ public void testSimple_BoxNotEnoughPairs() { "42.943 -71.032"); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -356,7 +353,7 @@ public void testGML_PointNotEnoughPairs() { + ""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -371,7 +368,7 @@ public void testGML_LineNotEnoughPairs() { + ""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -390,7 +387,7 @@ public void testGML_PolygonNotEnoughPairs() { + ""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -405,7 +402,7 @@ public void testGML_BoxMissingElement() { + ""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -413,7 +410,7 @@ public void test_NoShapes() { String xmlString = createExampleGeoRSS(""); java.util.List shapes = GeoRSSParser.parseShapes(xmlString); - assertNull("", shapes); + assertNull(shapes, ""); } @Test @@ -430,33 +427,33 @@ public void test_MultipleShapes() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() >= 2); - assertNotNull("", shapes.get(0)); - assertNotNull("", shapes.get(1)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() >= 2, ""); + assertNotNull(shapes.get(0), ""); + assertNotNull(shapes.get(1), ""); // is translated to a WWJ Path. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); // is translated to a WWJ Path when an elevation is specified. - assertTrue("", shapes.get(1) instanceof Path); + assertTrue(shapes.get(1) instanceof Path, ""); Path shape; java.util.List positions; shape = (Path) shapes.get(0); positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2), ""); shape = (Path) shapes.get(1); positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2), ""); } @Test @@ -466,19 +463,19 @@ public void test_CommaDelimitedCoordinates() { java.util.List shapes = GeoRSSParser.parseShapes(xmlString); // Parsed shapes list should have at least one non-null element. - assertNotNull("", shapes); - assertTrue("", shapes.size() != 0); - assertNotNull("", shapes.get(0)); + assertNotNull(shapes, ""); + assertTrue(shapes.size() != 0, ""); + assertNotNull(shapes.get(0), ""); // is translated to a WWJ Path. - assertTrue("", shapes.get(0) instanceof Path); + assertTrue(shapes.get(0) instanceof Path, ""); Path shape = (Path) shapes.get(0); java.util.List positions = (java.util.List) shape.getPositions(); - assertNotNull("", positions); - assertEquals("", 3, positions.size()); - assertEquals("", Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0)); - assertEquals("", Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1)); - assertEquals("", Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2)); + assertNotNull(positions, ""); + assertEquals(3, positions.size(), ""); + assertEquals(Position.fromDegrees(45.256, -110.45, 0.0), positions.get(0), ""); + assertEquals(Position.fromDegrees(46.46, -109.48, 0.0), positions.get(1), ""); + assertEquals(Position.fromDegrees(43.84, -109.86, 0.0), positions.get(2), ""); } ////////////////////////////////////////////////////////// diff --git a/test/gov/nasa/worldwind/formats/shapefile/ShapefileTest.java b/test/gov/nasa/worldwind/formats/shapefile/ShapefileTest.java index d2189561ac..cff942a240 100644 --- a/test/gov/nasa/worldwind/formats/shapefile/ShapefileTest.java +++ b/test/gov/nasa/worldwind/formats/shapefile/ShapefileTest.java @@ -31,17 +31,13 @@ import gov.nasa.worldwind.exception.WWRuntimeException; import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.util.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.io.File; import java.net.*; import java.util.Arrays; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class ShapefileTest { private static final String STATE_BOUNDS_PATH = "testData/shapefiles/state_bounds.shp"; @@ -56,7 +52,7 @@ public class ShapefileTest public void testOpenFile() { Shapefile shapefile = new Shapefile(new File(STATE_BOUNDS_PATH)); - assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYLINE, shapefile.getShapeType()); + assertEquals(Shapefile.SHAPE_POLYLINE, shapefile.getShapeType(), "Shape type is not as expected"); while (shapefile.hasNext()) { @@ -70,7 +66,7 @@ public void testOpenFile() public void testOpenPath() { Shapefile shapefile = new Shapefile(STATE_BOUNDS_PATH); - assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYLINE, shapefile.getShapeType()); + assertEquals(Shapefile.SHAPE_POLYLINE, shapefile.getShapeType(), "Shape type is not as expected"); while (shapefile.hasNext()) { @@ -84,7 +80,7 @@ public void testOpenPath() // public void testOpenURL() throws MalformedURLException // { // Shapefile shapefile = new Shapefile(new URL(SPRINGFIELD_URBAN_GROWTH_URL)); -// assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYGON, shapefile.getShapeType()); +// assertEquals(Shapefile.SHAPE_POLYGON, shapefile.getShapeType(), "Shape type is not as expected"); // // while (shapefile.hasNext()) // { @@ -98,7 +94,7 @@ public void testOpenPath() // public void testOpenURLString() // { // Shapefile shapefile = new Shapefile(SPRINGFIELD_URBAN_GROWTH_URL); -// assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYGON, shapefile.getShapeType()); +// assertEquals(Shapefile.SHAPE_POLYGON, shapefile.getShapeType(), "Shape type is not as expected"); // // while (shapefile.hasNext()) // { @@ -112,7 +108,7 @@ public void testOpenPath() public void testOpenSingleInputStream() throws Exception { Shapefile shapefile = new Shapefile(WWIO.openStream(STATE_BOUNDS_PATH)); - assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYLINE, shapefile.getShapeType()); + assertEquals(Shapefile.SHAPE_POLYLINE, shapefile.getShapeType(), "Shape type is not as expected"); while (shapefile.hasNext()) { @@ -130,7 +126,7 @@ public void testOpenMultipleInputStreams() throws Exception WWIO.openStream(WWIO.replaceSuffix(STATE_BOUNDS_PATH, ".shx")), WWIO.openStream(WWIO.replaceSuffix(STATE_BOUNDS_PATH, ".dbf")), WWIO.openStream(WWIO.replaceSuffix(STATE_BOUNDS_PATH, ".prj"))); - assertEquals("Shape type is not as expected", shapefile.getShapeType(), Shapefile.SHAPE_POLYLINE); + assertEquals(shapefile.getShapeType(), Shapefile.SHAPE_POLYLINE, "Shape type is not as expected"); while (shapefile.hasNext()) { @@ -148,7 +144,7 @@ public void testOpenMultipleInputStreams() throws Exception public void testUTMCoordinates() { Shapefile shapefile = new Shapefile(SPRINGFIELD_URBAN_GROWTH_PATH); - assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYGON, shapefile.getShapeType()); + assertEquals(Shapefile.SHAPE_POLYGON, shapefile.getShapeType(), "Shape type is not as expected"); assertShapefileAppearsNormal(shapefile); shapefile.close(); } @@ -157,7 +153,7 @@ public void testUTMCoordinates() public void testGeographicCoordinates() { Shapefile shapefile = new Shapefile(WORLD_BORDERS_PATH); - assertEquals("Shape type is not as expected", Shapefile.SHAPE_POLYGON, shapefile.getShapeType()); + assertEquals(Shapefile.SHAPE_POLYGON, shapefile.getShapeType(), "Shape type is not as expected"); assertShapefileAppearsNormal(shapefile); shapefile.close(); } @@ -188,13 +184,13 @@ public void testUnsupportedCoordinates() throws Exception public void testExpectedValuesForStateBounds() { Shapefile shapefile = new Shapefile(STATE_BOUNDS_PATH); - assertEquals("Version not as expected", 1000, shapefile.getVersion()); - assertEquals("Length not as expected", 2750692, shapefile.getLength()); - assertEquals("Shape type not as expected", Shapefile.SHAPE_POLYLINE, shapefile.getShapeType()); - assertEquals("Number of records not as expected", 19, shapefile.getNumberOfRecords()); - assertTrue("Bounds not as expected", Arrays.equals( + assertEquals(1000, shapefile.getVersion(), "Version not as expected"); + assertEquals(2750692, shapefile.getLength(), "Length not as expected"); + assertEquals(Shapefile.SHAPE_POLYLINE, shapefile.getShapeType(), "Shape type not as expected"); + assertEquals(19, shapefile.getNumberOfRecords(), "Number of records not as expected"); + assertTrue(Arrays.equals( new double[] {25.837377, 49.384359, -124.211606, -67.158958}, - shapefile.getBoundingRectangle())); + shapefile.getBoundingRectangle()), "Bounds not as expected"); while (shapefile.hasNext()) { @@ -204,20 +200,19 @@ public void testExpectedValuesForStateBounds() if (record.getRecordNumber() != 19) continue; - assertTrue("Record type not as expected", Shapefile.isPolylineType(record.getShapeType())); - assertEquals("Record number of parts not as expected", 1, record.getNumberOfParts()); - assertEquals("Record number of points not as expected", 10, record.getNumberOfPoints()); - assertEquals("Record first part number not as expected", 64, record.getFirstPartNumber()); - assertTrue("Record bounds not as expected", Arrays.equals( + assertTrue(Shapefile.isPolylineType(record.getShapeType()), "Record type not as expected"); + assertEquals(1, record.getNumberOfParts(), "Record number of parts not as expected"); + assertEquals(10, record.getNumberOfPoints(), "Record number of points not as expected"); + assertEquals(64, record.getFirstPartNumber(), "Record first part number not as expected"); + assertTrue(Arrays.equals( new double[] {39.5345, 39.53649, -75.530616, -75.527447}, - record.getBoundingRectangle())); + record.getBoundingRectangle()), "Record bounds not as expected"); - assertEquals("Record point not as expected", LatLon.fromDegrees(39.53649, -75.530616), - record.getPointBuffer(0).getLocation(0)); + assertEquals(LatLon.fromDegrees(39.53649, -75.530616), record.getPointBuffer(0).getLocation(0), "Record point not as expected"); - assertNotNull("Record attributes is null", record.getAttributes()); - assertEquals("Record attribute not as expected", 912L, record.getAttributes().getValue("ID")); - assertEquals("Record attribute not as expected", 0.004, record.getAttributes().getValue("LENGTH")); + assertNotNull(record.getAttributes(), "Record attributes is null"); + assertEquals(912L, record.getAttributes().getValue("ID"), "Record attribute not as expected"); + assertEquals(0.004, record.getAttributes().getValue("LENGTH"), "Record attribute not as expected"); } shapefile.close(); @@ -236,7 +231,7 @@ public static void assertShapefileAppearsNormal(Shapefile shapefile) { ShapefileRecord record = shapefile.nextRecord(); assertRecordAppearsNormal(shapefile, record); - assertTrue("Record type not Polygon", Shapefile.isPolygonType(record.getShapeType())); + assertTrue(Shapefile.isPolygonType(record.getShapeType()), "Record type not Polygon"); rect = record.getBoundingRectangle(); assertCoordAppearsGeographic("Record bounds not geographic", rect[2], rect[0]); @@ -251,51 +246,51 @@ public static void assertShapefileAppearsNormal(Shapefile shapefile) public static void assertRecordAppearsNormal(Shapefile shapefile, ShapefileRecord record) { - assertNotNull("Record is null", record); - assertSame("Record shapefile is not as expected", shapefile, record.getShapeFile()); - assertTrue("Record has no parts", record.getNumberOfParts() > 0); - assertTrue("Record has no points", record.getNumberOfPoints() > 0); - assertFalse("Record has no type", WWUtil.isEmpty(record.getShapeType())); + assertNotNull(record, "Record is null"); + assertSame(shapefile, record.getShapeFile(), "Record shapefile is not as expected"); + assertTrue(record.getNumberOfParts() > 0, "Record has no parts"); + assertTrue(record.getNumberOfPoints() > 0, "Record has no points"); + assertFalse(WWUtil.isEmpty(record.getShapeType()), "Record has no type"); if (Shapefile.isNullType(record.getShapeType())) - assertTrue("Record type is not as expected", record instanceof ShapefileRecordNull); + assertTrue(record instanceof ShapefileRecordNull, "Record type is not as expected"); else if (Shapefile.isPointType(record.getShapeType())) - assertTrue("Record type is not as expected", record instanceof ShapefileRecordPoint); + assertTrue(record instanceof ShapefileRecordPoint, "Record type is not as expected"); else if (Shapefile.isMultiPointType(record.getShapeType())) - assertTrue("Record type is not as expected", record instanceof ShapefileRecordMultiPoint); + assertTrue(record instanceof ShapefileRecordMultiPoint, "Record type is not as expected"); else if (Shapefile.isPolylineType(record.getShapeType())) - assertTrue("Record type is not as expected", record instanceof ShapefileRecordPolyline); + assertTrue(record instanceof ShapefileRecordPolyline, "Record type is not as expected"); else if (Shapefile.isPolygonType(record.getShapeType())) - assertTrue("Record type is not as expected", record instanceof ShapefileRecordPolygon); + assertTrue(record instanceof ShapefileRecordPolygon, "Record type is not as expected"); int expectedNumPoints = record.getNumberOfPoints(); int actualNumPoints = 0; // Accumulated in the loop below. for (int i = 0; i < record.getNumberOfParts(); i++) { - assertNotNull("Record point buffer is null", record.getPointBuffer(i)); + assertNotNull(record.getPointBuffer(i), "Record point buffer is null"); actualNumPoints += record.getPointBuffer(i).getSize(); } - assertEquals("Record num points is not as expected", expectedNumPoints, actualNumPoints); - assertNotNull("Record compound point buffer is null", record.getCompoundPointBuffer()); + assertEquals(expectedNumPoints, actualNumPoints, "Record num points is not as expected"); + assertNotNull(record.getCompoundPointBuffer(), "Record compound point buffer is null"); } public static void assertBoundingRectangleAppearsGeographic(String message, double[] coords) { - assertTrue(message, Angle.isValidLatitude(coords[0])); - assertTrue(message, Angle.isValidLatitude(coords[1])); - assertTrue(message, Angle.isValidLongitude(coords[2])); - assertTrue(message, Angle.isValidLongitude(coords[3])); + assertTrue(Angle.isValidLatitude(coords[0]), message); + assertTrue(Angle.isValidLatitude(coords[1]), message); + assertTrue(Angle.isValidLongitude(coords[2]), message); + assertTrue(Angle.isValidLongitude(coords[3]), message); } public static void assertCoordAppearsGeographic(String message, double x, double y) { - assertTrue(message, Angle.isValidLongitude(x)); - assertTrue(message, Angle.isValidLatitude(y)); + assertTrue(Angle.isValidLongitude(x), message); + assertTrue(Angle.isValidLatitude(y), message); } } diff --git a/test/gov/nasa/worldwind/geom/AngleTest.java b/test/gov/nasa/worldwind/geom/AngleTest.java index c2ea9acd7e..61b5bff994 100644 --- a/test/gov/nasa/worldwind/geom/AngleTest.java +++ b/test/gov/nasa/worldwind/geom/AngleTest.java @@ -28,13 +28,9 @@ package gov.nasa.worldwind.geom; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class AngleTest { private static final double DELTA = 1e-9; @@ -49,7 +45,7 @@ public void testFromDMS_lessThanZeroDegrees() } catch (Exception e) { - assertTrue("Should raise an IllegalArgumentException", e instanceof IllegalArgumentException); + assertTrue(e instanceof IllegalArgumentException, "Should raise an IllegalArgumentException"); } } @@ -63,7 +59,7 @@ public void testFromDMS_lessThanZeroMinutes() } catch (Exception e) { - assertTrue("Should raise an IllegalArgumentException", e instanceof IllegalArgumentException); + assertTrue(e instanceof IllegalArgumentException, "Should raise an IllegalArgumentException"); } } @@ -77,7 +73,7 @@ public void testFromDMS_lessThanZeroSeconds() } catch (Exception e) { - assertTrue("Should raise an IllegalArgumentException", e instanceof IllegalArgumentException); + assertTrue(e instanceof IllegalArgumentException, "Should raise an IllegalArgumentException"); } } @@ -91,7 +87,7 @@ public void testFromDMS_ZeroDegree() Angle angle = Angle.fromDMS(degrees, minutes, seconds); - assertEquals("test with zero degrees", expectedDegrees, angle.degrees, DELTA); + assertEquals(expectedDegrees, angle.degrees, DELTA, "test with zero degrees"); } @Test @@ -104,7 +100,7 @@ public void testFromDMS_AboveZeroDegrees() Angle angle = Angle.fromDMS(degrees, minutes, seconds); - assertEquals("test with zero degrees", expectedDegrees, angle.degrees, DELTA); + assertEquals(expectedDegrees, angle.degrees, DELTA, "test with zero degrees"); } @Test @@ -117,7 +113,7 @@ public void testFromDMdS_lessThanZeroDegrees() } catch (Exception e) { - assertTrue("Should raise an IllegalArgumentException", e instanceof IllegalArgumentException); + assertTrue(e instanceof IllegalArgumentException, "Should raise an IllegalArgumentException"); } } @@ -131,7 +127,7 @@ public void testFromDMdS_lessThanZeroMinutes() } catch (Exception e) { - assertTrue("Should raise an IllegalArgumentException", e instanceof IllegalArgumentException); + assertTrue(e instanceof IllegalArgumentException, "Should raise an IllegalArgumentException"); } } @@ -145,7 +141,7 @@ public void testFromDMdS_ZeroDegree() Angle angle = Angle.fromDMdS(degrees, minutes + seconds / 60d); - assertEquals("test with zero degrees", expectedDegrees, angle.degrees, DELTA); + assertEquals(expectedDegrees, angle.degrees, DELTA, "test with zero degrees"); } @Test @@ -158,7 +154,7 @@ public void testFromDMdS_AboveZeroDegrees() Angle angle = Angle.fromDMdS(degrees, minutes + seconds / 60d); - assertEquals("test with zero degrees", expectedDegrees, angle.degrees, DELTA); + assertEquals(expectedDegrees, angle.degrees, DELTA, "test with zero degrees"); } @Test @@ -172,7 +168,7 @@ public void testFromDMString_PositiveCoordinate() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("standard positive format", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "standard positive format"); } @Test @@ -186,7 +182,7 @@ public void testFromDMString_PositiveSign() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("positive prefix format", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "positive prefix format"); } @Test @@ -200,7 +196,7 @@ public void testFromDMString_PositiveDirection() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("positive direction format", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "positive direction format"); } @Test @@ -214,7 +210,7 @@ public void testFromDMString_NegativeSign() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("negative prefix format", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "negative prefix format"); } @Test @@ -228,7 +224,7 @@ public void testFromDMString_NegativeDirection() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("negative direction format", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "negative direction format"); } @Test @@ -242,8 +238,7 @@ public void testFromDMSString_ConflictingPrefixSuffixCaseOne() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("conflicting string format, positive sign and negative direction", expectedValue, actualValue, - 0.0); + assertEquals(expectedValue, actualValue, 0.0, "conflicting string format, positive sign and negative direction"); } @Test @@ -257,8 +252,7 @@ public void testFromDMSString_ConflictingPrefixSuffixCaseTwo() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("conflicting string format, negative sign and positive direction", expectedValue, actualValue, - 0.0); + assertEquals(expectedValue, actualValue, 0.0, "conflicting string format, negative sign and positive direction"); } @Test @@ -272,8 +266,7 @@ public void testFromDMSString_ConflictingPrefixSuffixCaseThree() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("conflicting string format, negative sign and negative direction", expectedValue, actualValue, - 0.0); + assertEquals(expectedValue, actualValue, 0.0, "conflicting string format, negative sign and negative direction"); } @Test @@ -287,6 +280,6 @@ public void testFromDMSString_ConflictingPrefixSuffixCaseFour() double actualValue = Angle.fromDMS(angleString).degrees; - assertEquals("conflicting string format, positive sign and direction", expectedValue, actualValue, 0.0); + assertEquals(expectedValue, actualValue, 0.0, "conflicting string format, positive sign and direction"); } } diff --git a/test/gov/nasa/worldwind/geom/BoundingVolumeTest.java b/test/gov/nasa/worldwind/geom/BoundingVolumeTest.java index a60e45a65f..0738e58444 100644 --- a/test/gov/nasa/worldwind/geom/BoundingVolumeTest.java +++ b/test/gov/nasa/worldwind/geom/BoundingVolumeTest.java @@ -29,13 +29,11 @@ package gov.nasa.worldwind.geom; import gov.nasa.worldwind.globes.*; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class BoundingVolumeTest { private Sector sector; @@ -45,14 +43,14 @@ public class BoundingVolumeTest private double maxElevation = 1e3; private int numIterations = (int) 1e6; - @Before + @BeforeEach public void setUp() { this.globe = new Earth(); this.sector = Sector.fromDegrees(-20, -10, -15, -10); } - @After + @AfterEach public void tearDown() { this.globe = null; @@ -72,7 +70,7 @@ public void testBoxCulling() 1, 2, -1, 1, -1, 1); boolean tf = box.intersects(frustum); - assertTrue("Box/Frustum intersection not detected", tf); + assertTrue(tf, "Box/Frustum intersection not detected"); } @Test @@ -87,14 +85,14 @@ public void testSphereCulling() Sphere sphere = new Sphere(new Vec4(0, 0, 0, 1), 1); boolean tf = sphere.intersects(frustum); - assertTrue("sphere.intersects(frustum) intersection not detected", tf); + assertTrue(tf, "sphere.intersects(frustum) intersection not detected"); tf = frustum.intersects(sphere); - assertTrue("frustum.intersects(sphere) intersection not detected", tf); + assertTrue(tf, "frustum.intersects(sphere) intersection not detected"); sphere = new Sphere(new Vec4(3, 3, 3, 1), 1); tf = sphere.intersects(frustum); - assertFalse("sphere.intersects(frustum) erroneously detects intersection", tf); + assertFalse(tf, "sphere.intersects(frustum) erroneously detects intersection"); } @SuppressWarnings("UnusedAssignment") @@ -105,7 +103,7 @@ public void testBoxCullingSpeed() Box box = new Box(new Vec4(0, 0, 0)); boolean tf = box.intersects(frustum); - assertTrue("Box/Frustum intersection not detected", tf); + assertTrue(tf, "Box/Frustum intersection not detected"); for (int j = 0; j < 3; j++) { @@ -128,7 +126,7 @@ public void testCylinderCullingSpeed() Cylinder cyl = new Cylinder(new Vec4(0, 0.5, 0.5), new Vec4(1, 0.5, 0.5), 0.5); boolean tf = cyl.intersects(frustum); - assertTrue("Box/Frustum intersection not detected", tf); + assertTrue(tf, "Box/Frustum intersection not detected"); for (int j = 0; j < 3; j++) { diff --git a/test/gov/nasa/worldwind/geom/LatLonTest.java b/test/gov/nasa/worldwind/geom/LatLonTest.java index 898e90c6eb..af6cf25dbd 100644 --- a/test/gov/nasa/worldwind/geom/LatLonTest.java +++ b/test/gov/nasa/worldwind/geom/LatLonTest.java @@ -29,13 +29,11 @@ package gov.nasa.worldwind.geom; import gov.nasa.worldwind.globes.*; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class LatLonTest { private final static double DISTANCE_THRESHOLD = 1e-10; @@ -44,13 +42,13 @@ public class LatLonTest private Globe globe; - @Before + @BeforeEach public void setUp() { this.globe = new Earth(); } - @After + @AfterEach public void tearDown() { this.globe = null; @@ -66,7 +64,7 @@ public void testGreatCircleDistance_TrivialEquivalentPointsA() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 0.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial equivalent points A", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points A"); } @Test @@ -75,7 +73,7 @@ public void testGreatCircleDistance_TrivialEquivalentPointsB() LatLon begin = LatLon.fromDegrees(0.0, -180.0); LatLon end = LatLon.fromDegrees(0.0, 180.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial equivalent points B", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points B"); } @Test @@ -84,7 +82,7 @@ public void testGreatCircleDistance_TrivialEquivalentPointsC() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 360.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial equivalent points C", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points C"); } @Test @@ -93,7 +91,7 @@ public void testGreatCircleDistance_EquivalentPoints() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(53.0902505, 112.8935442); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Equivalent points", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Equivalent points"); } ////////////////////////////////////////////////////////// @@ -106,7 +104,7 @@ public void testGreatCircleDistance_TrivialAntipodalPointsA() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 180.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial antipodal points A", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Trivial antipodal points A"); } @Test @@ -115,7 +113,7 @@ public void testGreatCircleDistance_TrivialAntipodalPointsB() LatLon begin = LatLon.fromDegrees(-90.0, 0.0); LatLon end = LatLon.fromDegrees(90.0, 0.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial antipodal points B", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Trivial antipodal points B"); } @Test @@ -124,7 +122,7 @@ public void testGreatCircleDistance_TrivialAntipodalPointsC() LatLon begin = LatLon.fromDegrees(-90.0, -180.0); LatLon end = LatLon.fromDegrees(90.0, 180.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Trivial antipodal points C", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Trivial antipodal points C"); } @Test @@ -133,7 +131,7 @@ public void testGreatCircleDistance_AntipodalPointsA() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(-53.0902505, -67.1064558); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Antipodal points A", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Antipodal points A"); } @Test @@ -142,7 +140,7 @@ public void testGreatCircleDistance_AntipodalPointsB() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(12.0, -93.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Antipodal points B", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Antipodal points B"); } ////////////////////////////////////////////////////////// @@ -155,7 +153,7 @@ public void testGreatCircleDistance_KnownDistance() LatLon begin = LatLon.fromDegrees(90.0, 45.0); LatLon end = LatLon.fromDegrees(36.0, 180.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Known spherical distance", 54.0, distance, DISTANCE_THRESHOLD); + assertEquals(54.0, distance, DISTANCE_THRESHOLD, "Known spherical distance"); } @Test @@ -164,8 +162,7 @@ public void testGreatCircleDistance_KnownDistanceCloseToZero() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(-12.0000001, 86.9999999); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Known spherical distance (close to zero)", 1.3988468832247915e-7, distance, - DISTANCE_THRESHOLD); + assertEquals(1.3988468832247915e-7, distance, DISTANCE_THRESHOLD, "Known spherical distance (close to zero)"); } @Test @@ -174,7 +171,7 @@ public void testGreatCircleDistance_KnownDistanceCloseTo180() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(11.9999999, -93.0000001); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Known spherical distance (close to 180)", 180.0, distance, DISTANCE_THRESHOLD); + assertEquals(180.0, distance, DISTANCE_THRESHOLD, "Known spherical distance (close to 180)"); } ////////////////////////////////////////////////////////// @@ -187,7 +184,7 @@ public void testGreatCircleDistance_ProblemPointsA() LatLon begin = LatLon.fromDegrees(36.0, -118.0); LatLon end = LatLon.fromDegrees(36.0, -117.0); double distance = LatLon.greatCircleDistance(begin, end).degrees; - assertEquals("Problem points A", 0.8090134466773318, distance, DISTANCE_THRESHOLD); + assertEquals(0.8090134466773318, distance, DISTANCE_THRESHOLD, "Problem points A"); } ////////////////////////////////////////////////////////// @@ -200,7 +197,7 @@ public void testGreatCircleAzimuth_TrivialNorth() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(90, 0.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial North greatCircleAzimuth", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial North greatCircleAzimuth"); } @Test @@ -209,7 +206,7 @@ public void testGreatCircleAzimuth_TrivialEast() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 90.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial East greatCircleAzimuth", 90.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(90.0, azimuth, AZIMUTH_THRESHOLD, "Trivial East greatCircleAzimuth"); } @Test @@ -218,7 +215,7 @@ public void testGreatCircleAzimuth_TrivialSouth() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(-90.0, 0.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial South greatCircleAzimuth", 180.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(180.0, azimuth, AZIMUTH_THRESHOLD, "Trivial South greatCircleAzimuth"); } @Test @@ -227,7 +224,7 @@ public void testGreatCircleAzimuth_TrivialWest() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, -90.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial West greatCircleAzimuth", -90.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-90.0, azimuth, AZIMUTH_THRESHOLD, "Trivial West greatCircleAzimuth"); } ////////////////////////////////////////////////////////// @@ -241,7 +238,7 @@ public void testGreatCircleAzimuth_TrivialEquivalentPointsA() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 0.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial equivalent points A", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial equivalent points A"); } //@Test @@ -250,7 +247,7 @@ public void testGreatCircleAzimuth_TrivialEquivalentPointsA() // LatLon begin = LatLon.fromDegrees(0.0, -180.0); // LatLon end = LatLon.fromDegrees(0.0, 180.0); // double greatCircleAzimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - // assertEquals("Trivial equivalent points B", 0.0, greatCircleAzimuth, THRESHOLD); + // assertEquals(0.0, greatCircleAzimuth, THRESHOLD, "Trivial equivalent points B"); //} @Test @@ -259,7 +256,7 @@ public void testGreatCircleAzimuth_TrivialEquivalentPointsC() LatLon begin = LatLon.fromDegrees(90.0, 0.0); LatLon end = LatLon.fromDegrees(90.0, 0.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Trivial equivalent points C", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial equivalent points C"); } //@Test @@ -268,7 +265,7 @@ public void testGreatCircleAzimuth_TrivialEquivalentPointsC() // LatLon begin = LatLon.fromDegrees(90.0, 0.0); // LatLon end = LatLon.fromDegrees(90.0, 45.0); // double greatCircleAzimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - // assertEquals("Trivial equivalent points D", 0.0, greatCircleAzimuth, THRESHOLD); + // assertEquals(0.0, greatCircleAzimuth, THRESHOLD, "Trivial equivalent points D"); //} @Test @@ -277,7 +274,7 @@ public void testGreatCircleAzimuth_EquivalentPoints() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(53.0902505, 112.8935442); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Equivalent points", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Equivalent points"); } ////////////////////////////////////////////////////////// @@ -290,7 +287,7 @@ public void testGreatCircleAzimuth_KnownAzimuthA() LatLon begin = LatLon.fromDegrees(-90.0, -180.0); LatLon end = LatLon.fromDegrees(90.0, 180.0); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Known Azimuth A", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth A"); } @Test @@ -299,7 +296,7 @@ public void testGreatCircleAzimuth_KnownAzimuthB() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(-53.0902505, -67.1064558); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Known Azimuth B", -90.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-90.0, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth B"); } @Test @@ -308,7 +305,7 @@ public void testGreatCircleAzimuth_KnownAzimuthC() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(-12.0000001, 86.9999999); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Known Azimuth C", -135.6329170237546, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-135.6329170237546, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth C"); } @Test @@ -317,7 +314,7 @@ public void testGreatCircleAzimuth_KnownAzimuthD() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(11.9999999, -93.0000001); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Known Azimuth D", 135.6329170162944, azimuth, AZIMUTH_THRESHOLD); + assertEquals(135.6329170162944, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth D"); } @Test @@ -326,7 +323,7 @@ public void testGreatCircleAzimuth_KnownAzimuthE() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(53.0902505, -67.1064558); double azimuth = LatLon.greatCircleAzimuth(begin, end).degrees; - assertEquals("Known Azimuth E", -21.38356223882703, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-21.38356223882703, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth E"); } ////////////////////////////////////////////////////////// @@ -341,8 +338,8 @@ public void testGreatCircleEndPosition_TrivialDistanceA() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(0.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial distance A (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial distance A (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial distance A (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial distance A (lon)"); } @Test @@ -352,8 +349,8 @@ public void testGreatCircleEndPosition_TrivialDistanceB() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(360.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial distance B (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial distance B (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial distance B (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial distance B (lon)"); } @Test @@ -363,8 +360,8 @@ public void testGreatCircleEndPosition_TrivialAzimuthA() double azimuthRadians = Math.toRadians(90.0); double distanceRadians = Math.toRadians(0.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial Azimuth A (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial Azimuth A (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth A (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth A (lon)"); } @Test @@ -374,8 +371,8 @@ public void testGreatCircleEndPosition_TrivialAzimuthB() double azimuthRadians = Math.toRadians(90.0); double distanceRadians = Math.toRadians(360.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial Azimuth B (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial Azimuth B (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth B (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth B (lon)"); } ////////////////////////////////////////////////////////// @@ -390,8 +387,8 @@ public void testGreatCircleEndPosition_TrivialAntipodalPointsA() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(180.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial antipodal points A (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial antipodal points A (lon)", 180.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points A (lat)"); + assertEquals(180.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points A (lon)"); } @Test @@ -401,8 +398,8 @@ public void testGreatCircleEndPosition_TrivialAntipodalPointsB() double azimuthRadians = Math.toRadians(90.0); double distanceRadians = Math.toRadians(180.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial antipodal points B (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial antipodal points B (lon)", 180.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points B (lat)"); + assertEquals(180.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points B (lon)"); } @Test @@ -412,8 +409,8 @@ public void testGreatCircleEndPosition_TrivialAntipodalPointsC() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(180.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial antipodal points C (lat)", 90.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial antipodal points C (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(90.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points C (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial antipodal points C (lon)"); } @Test @@ -423,8 +420,8 @@ public void testGreatCircleEndPosition_AntipodalPointsA() double azimuthRadians = Math.toRadians(-90.0); double distanceRadians = Math.toRadians(180.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Antipodal points A (lat)", -53.0902505, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Antipodal points A (lon)", -67.1064558, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(-53.0902505, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Antipodal points A (lat)"); + assertEquals(-67.1064558, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Antipodal points A (lon)"); } @Test @@ -434,8 +431,8 @@ public void testGreatCircleEndPosition_AntipodalPointsB() double azimuthRadians = Math.toRadians(-90.0); double distanceRadians = Math.toRadians(180.0); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Antipodal points B (lat)", 12.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Antipodal points B (lon)", -93.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(12.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Antipodal points B (lat)"); + assertEquals(-93.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Antipodal points B (lon)"); } ////////////////////////////////////////////////////////// @@ -449,8 +446,8 @@ public void testGreatCircleEndPosition_KnownPointsA() double azimuthRadians = Math.toRadians(15.2204311); double distanceRadians = Math.toRadians(-88.7560694); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Known points A (lat)", -36.63477988750917, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Known points A (lon)", 131.98550742812412, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(-36.63477988750917, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Known points A (lat)"); + assertEquals(131.98550742812412, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Known points A (lon)"); } @Test @@ -460,8 +457,8 @@ public void testGreatCircleEndPosition_KnownPointsB() double azimuthRadians = Math.toRadians(-68.4055227); double distanceRadians = Math.toRadians(10.53630354); LatLon end = LatLon.greatCircleEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Known points B (lat)", 55.7426290038835, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Known points B (lon)", 95.313127193979270, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(55.7426290038835, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Known points B (lat)"); + assertEquals(95.313127193979270, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Known points B (lon)"); } ////////////////////////////////////////////////////////// @@ -474,7 +471,7 @@ public void testRhumbDistance_RhumbDistance_TrivialEquivalentPointsA() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 0.0); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Trivial equivalent points A", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points A"); } @Test @@ -483,7 +480,7 @@ public void testRhumbDistance_TrivialEquivalentPointsB() LatLon begin = LatLon.fromDegrees(0.0, -180.0); LatLon end = LatLon.fromDegrees(0.0, 180.0); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Trivial equivalent points B", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points B"); } @Test @@ -492,7 +489,7 @@ public void testRhumbDistance_TrivialEquivalentPointsC() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 360.0); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Trivial equivalent points C", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Trivial equivalent points C"); } @Test @@ -501,7 +498,7 @@ public void testRhumbDistance_EquivalentPoints() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(53.0902505, 112.8935442); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Equivalent points", 0.0, distance, DISTANCE_THRESHOLD); + assertEquals(0.0, distance, DISTANCE_THRESHOLD, "Equivalent points"); } ////////////////////////////////////////////////////////// @@ -514,7 +511,7 @@ public void testRhumbDistance_KnownDistance() LatLon begin = LatLon.fromDegrees(90.0, 45.0); LatLon end = LatLon.fromDegrees(36.0, 180.0); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Known spherical distance", 54.11143196539475, distance, 1e-5); // Custom threshold + assertEquals(54.11143196539475, distance, 1e-5, "Known spherical distance"); // Custom threshold } @Test @@ -523,7 +520,7 @@ public void testRhumbDistance_KnownDistanceCloseToZero() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(-12.0000001, 86.9999999); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Known spherical distance (close to zero)", 1.398846933590201e-7, distance, DISTANCE_THRESHOLD); + assertEquals(1.398846933590201e-7, distance, DISTANCE_THRESHOLD, "Known spherical distance (close to zero)"); } @Test @@ -532,7 +529,7 @@ public void testRhumbDistance_KnownDistanceCloseTo180() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(11.9999999, -93.0000001); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Known spherical distance (close to 180)", 180.28382072652187, distance, DISTANCE_THRESHOLD); + assertEquals(180.28382072652187, distance, DISTANCE_THRESHOLD, "Known spherical distance (close to 180)"); } ////////////////////////////////////////////////////////// @@ -545,7 +542,7 @@ public void testRhumbDistance_ProblemPointsA() LatLon begin = LatLon.fromDegrees(36.0, -118.0); LatLon end = LatLon.fromDegrees(36.0, -117.0); double distance = LatLon.rhumbDistance(begin, end).degrees; - assertEquals("Problem points A", 0.8090169943749475, distance, DISTANCE_THRESHOLD); + assertEquals(0.8090169943749475, distance, DISTANCE_THRESHOLD, "Problem points A"); } ////////////////////////////////////////////////////////// @@ -558,7 +555,7 @@ public void testRhumbAzimuth_TrivialNorth() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(90, 0.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial North rhumbAzimuth", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial North rhumbAzimuth"); } @Test @@ -567,7 +564,7 @@ public void testRhumbAzimuth_TrivialEast() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 90.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial East rhumbAzimuth", 90.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(90.0, azimuth, AZIMUTH_THRESHOLD, "Trivial East rhumbAzimuth"); } @Test @@ -576,7 +573,7 @@ public void testRhumbAzimuth_TrivialSouth() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(-90.0, 0.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial South rhumbAzimuth", 180.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(180.0, azimuth, AZIMUTH_THRESHOLD, "Trivial South rhumbAzimuth"); } @Test @@ -585,7 +582,7 @@ public void testRhumbAzimuth_TrivialWest() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, -90.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial West rhumbAzimuth", -90.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-90.0, azimuth, AZIMUTH_THRESHOLD, "Trivial West rhumbAzimuth"); } ////////////////////////////////////////////////////////// @@ -599,7 +596,7 @@ public void testRhumbAzimuth_TrivialEquivalentPointsA() LatLon begin = LatLon.fromDegrees(0.0, 0.0); LatLon end = LatLon.fromDegrees(0.0, 0.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial equivalent points A", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial equivalent points A"); } //@Test @@ -608,7 +605,7 @@ public void testRhumbAzimuth_TrivialEquivalentPointsA() // LatLon begin = LatLon.fromDegrees(0.0, -180.0); // LatLon end = LatLon.fromDegrees(0.0, 180.0); // double rhumbAzimuth = LatLon.rhumbAzimuth(begin, end).degrees; - // assertEquals("Trivial equivalent points B", 0.0, rhumbAzimuth, THRESHOLD); + // assertEquals(0.0, rhumbAzimuth, THRESHOLD, "Trivial equivalent points B"); //} @Test @@ -617,7 +614,7 @@ public void testRhumbAzimuth_TrivialEquivalentPointsC() LatLon begin = LatLon.fromDegrees(90.0, 0.0); LatLon end = LatLon.fromDegrees(90.0, 0.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Trivial equivalent points C", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Trivial equivalent points C"); } //@Test @@ -626,7 +623,7 @@ public void testRhumbAzimuth_TrivialEquivalentPointsC() // LatLon begin = LatLon.fromDegrees(90.0, 0.0); // LatLon end = LatLon.fromDegrees(90.0, 45.0); // double rhumbAzimuth = LatLon.rhumbAzimuth(begin, end).degrees; - // assertEquals("Trivial equivalent points D", 0.0, rhumbAzimuth, THRESHOLD); + // assertEquals(0.0, rhumbAzimuth, THRESHOLD, "Trivial equivalent points D"); //} @Test @@ -635,7 +632,7 @@ public void testRhumbAzimuth_EquivalentPoints() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(53.0902505, 112.8935442); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Equivalent points", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Equivalent points"); } ////////////////////////////////////////////////////////// @@ -648,7 +645,7 @@ public void testRhumbAzimuth_KnownAzimuthA() LatLon begin = LatLon.fromDegrees(-90.0, -180.0); LatLon end = LatLon.fromDegrees(90.0, 180.0); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Known Azimuth A", 0.0, azimuth, AZIMUTH_THRESHOLD); + assertEquals(0.0, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth A"); } @Test @@ -657,7 +654,7 @@ public void testRhumbAzimuth_KnownAzimuthB() LatLon begin = LatLon.fromDegrees(53.0902505, 112.8935442); LatLon end = LatLon.fromDegrees(-53.0902505, -67.1064558); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Known Azimuth B", -124.94048502315054, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-124.94048502315054, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth B"); } @Test @@ -666,7 +663,7 @@ public void testRhumbAzimuth_KnownAzimuthC() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(-12.0000001, 86.9999999); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Known Azimuth C", -135.63291443992495, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-135.63291443992495, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth C"); } @Test @@ -675,7 +672,7 @@ public void testRhumbAzimuth_KnownAzimuthD() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(11.9999999, -93.0000001); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Known Azimuth D", 82.34987931207793, azimuth, AZIMUTH_THRESHOLD); + assertEquals(82.34987931207793, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth D"); } @Test @@ -684,7 +681,7 @@ public void testRhumbAzimuth_KnownAzimuthE() LatLon begin = LatLon.fromDegrees(-12.0, 87.0); LatLon end = LatLon.fromDegrees(53.0902505, -67.1064558); double azimuth = LatLon.rhumbAzimuth(begin, end).degrees; - assertEquals("Known Azimuth E", -64.05846977747626, azimuth, AZIMUTH_THRESHOLD); + assertEquals(-64.05846977747626, azimuth, AZIMUTH_THRESHOLD, "Known Azimuth E"); } ////////////////////////////////////////////////////////// @@ -699,8 +696,8 @@ public void testRhumEndPosition_TrivialDistanceA() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(0.0); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial distance A (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial distance A (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial distance A (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial distance A (lon)"); } @Test @@ -710,8 +707,8 @@ public void testRhumEndPosition_TrivialDistanceB() double azimuthRadians = Math.toRadians(0.0); double distanceRadians = Math.toRadians(360.0); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial distance B (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial distance B (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial distance B (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial distance B (lon)"); } @Test @@ -721,8 +718,8 @@ public void testRhumEndPosition_TrivialAzimuthA() double azimuthRadians = Math.toRadians(90.0); double distanceRadians = Math.toRadians(0.0); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial Azimuth A (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial Azimuth A (lon)", 0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth A (lat)"); + assertEquals(0.0, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth A (lon)"); } @Test @@ -732,9 +729,8 @@ public void testRhumEndPosition_TrivialAzimuthB() double azimuthRadians = Math.toRadians(90.0); double distanceRadians = Math.toRadians(360.0); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Trivial Azimuth B (lat)", 0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Trivial Azimuth B (lon)", 0.0, end.getLongitude().degrees, - 1e-1); // Custom threshold + assertEquals(0.0, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Trivial Azimuth B (lat)"); + assertEquals(0.0, end.getLongitude().degrees, 1e-1, "Trivial Azimuth B (lon)"); // Custom threshold } ////////////////////////////////////////////////////////// @@ -748,8 +744,8 @@ public void testRhumEndPosition_KnownPointsA() double azimuthRadians = Math.toRadians(15.2204311); double distanceRadians = Math.toRadians(88.7560694); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Known points A (lat)", 32.55251684755035, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Known points A (lon)", -40.62266365697857, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(32.55251684755035, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Known points A (lat)"); + assertEquals(-40.62266365697857, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Known points A (lon)"); } @Test @@ -759,8 +755,8 @@ public void testRhumEndPosition_KnownPointsB() double azimuthRadians = Math.toRadians(-68.4055227); double distanceRadians = Math.toRadians(10.53630354); LatLon end = LatLon.rhumbEndPosition(begin, azimuthRadians, distanceRadians); - assertEquals("Known points B (lat)", 56.9679782407693, end.getLatitude().degrees, DISTANCE_THRESHOLD); - assertEquals("Known points B (lon)", 95.78434282105843, end.getLongitude().degrees, DISTANCE_THRESHOLD); + assertEquals(56.9679782407693, end.getLatitude().degrees, DISTANCE_THRESHOLD, "Known points B (lat)"); + assertEquals(95.78434282105843, end.getLongitude().degrees, DISTANCE_THRESHOLD, "Known points B (lon)"); } ////////////////////////////////////////////////////////// @@ -777,10 +773,8 @@ public void testRhumEndPosition_ProblemPointsA() Angle distance = Angle.fromDegrees(8.963656110719409); LatLon begin = LatLon.fromRadians(initialLat.getRadians(), initialLon.getRadians()); LatLon end = LatLon.rhumbEndPosition(begin, azimuth, distance); - assertEquals("Problem points A (lat)", initialLat.getDegrees(), end.getLatitude().getDegrees(), - DISTANCE_THRESHOLD); - assertEquals("Problem points A (lon)", -12.391252821313167, end.getLongitude().getDegrees(), - DISTANCE_THRESHOLD); + assertEquals(initialLat.getDegrees(), end.getLatitude().getDegrees(), DISTANCE_THRESHOLD, "Problem points A (lat)"); + assertEquals(-12.391252821313167, end.getLongitude().getDegrees(), DISTANCE_THRESHOLD, "Problem points A (lon)"); } @Test @@ -790,7 +784,7 @@ public void testEllipsoidalDistance_KnownDistanceA() LatLon end = LatLon.fromDegrees(34.413929, -97.022765); double distance = LatLon.ellipsoidalDistance(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal distance A", 638027.750, distance, TOLERANCE); + assertEquals(638027.750, distance, TOLERANCE, "Known ellipsoidal distance A"); } @Test @@ -800,7 +794,7 @@ public void testEllipsoidalDistance_KnownDistanceB() LatLon end = LatLon.fromDegrees(48.4216, -122.3352); double distance = LatLon.ellipsoidalDistance(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal distance B", 5900926.896, distance, TOLERANCE); + assertEquals(5900926.896, distance, TOLERANCE, "Known ellipsoidal distance B"); } @Test @@ -810,7 +804,7 @@ public void testEllipsoidalDistance_KnownDistanceC() LatLon end = LatLon.fromDegrees(23.6937, 121.9831); double distance = LatLon.ellipsoidalDistance(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal distance C", 6186281.864, distance, TOLERANCE); + assertEquals(6186281.864, distance, TOLERANCE, "Known ellipsoidal distance C"); } @Test @@ -820,7 +814,7 @@ public void testEllipsoidalDistance_KnownDistanceD() LatLon end = LatLon.fromDegrees(42.3232, -71.0974); double distance = LatLon.ellipsoidalDistance(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal distance D", 5296396.967, distance, TOLERANCE); + assertEquals(5296396.967, distance, TOLERANCE, "Known ellipsoidal distance D"); } @Test @@ -831,7 +825,7 @@ public void testEllipsoidalDistance_Antipodal() LatLon end = LatLon.fromDegrees(12.186856600402097, -121.90490684689753); double distance = LatLon.ellipsoidalDistance(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Antipodal", 1.9937004080007866E7, distance, TOLERANCE); + assertEquals(1.9937004080007866E7, distance, TOLERANCE, "Antipodal"); } @Test @@ -841,7 +835,7 @@ public void testEllipsoidalForwardAzimuth_KnownAzimuthA() LatLon end = LatLon.fromDegrees(34.000000, -97.000000); Angle theta = LatLon.ellipsoidalForwardAzimuth(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal Azimuth A", 45.50583, theta.degrees, TOLERANCE); + assertEquals(45.50583, theta.degrees, TOLERANCE, "Known ellipsoidal Azimuth A"); } @Test @@ -851,8 +845,7 @@ public void testEllipsoidalForwardAzimuth_KnownAzimuthB() LatLon end = LatLon.fromDegrees(48.0000, -122.0000); Angle theta = LatLon.ellipsoidalForwardAzimuth(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal Azimuth B", Angle.normalizedLongitude(Angle.fromDegrees(325.10111)).degrees, - theta.degrees, TOLERANCE); + assertEquals(Angle.normalizedLongitude(Angle.fromDegrees(325.10111)).degrees, theta.degrees, TOLERANCE, "Known ellipsoidal Azimuth B"); } @Test @@ -862,7 +855,7 @@ public void testEllipsoidalForwardAzimuth_KnownAzimuthC() LatLon end = LatLon.fromDegrees(23.0000, 122.0000); Angle theta = LatLon.ellipsoidalForwardAzimuth(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal Azimuth C", 6.75777, theta.degrees, TOLERANCE); + assertEquals(6.75777, theta.degrees, TOLERANCE, "Known ellipsoidal Azimuth C"); } @Test @@ -872,7 +865,6 @@ public void testEllipsoidalForwardAzimuth_KnownAzimuthD() LatLon end = LatLon.fromDegrees(42.0000, -71.0000); Angle theta = LatLon.ellipsoidalForwardAzimuth(begin, end, globe.getEquatorialRadius(), globe.getPolarRadius()); - assertEquals("Known ellipsoidal Azimuth D", Angle.normalizedLongitude(Angle.fromDegrees(287.95372)).degrees, - theta.degrees, TOLERANCE); + assertEquals(Angle.normalizedLongitude(Angle.fromDegrees(287.95372)).degrees, theta.degrees, TOLERANCE, "Known ellipsoidal Azimuth D"); } } diff --git a/test/gov/nasa/worldwind/geom/LineTest.java b/test/gov/nasa/worldwind/geom/LineTest.java index 34de3e0f5f..22f064bd4d 100644 --- a/test/gov/nasa/worldwind/geom/LineTest.java +++ b/test/gov/nasa/worldwind/geom/LineTest.java @@ -27,13 +27,9 @@ */ package gov.nasa.worldwind.geom; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class LineTest { @Test @@ -46,33 +42,32 @@ public void testFrustumClipping() pa = Vec4.ZERO; pb = new Vec4(1, 0, 0); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Trivial accept A", clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb)); + assertTrue(clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb), "Trivial accept A"); pa = Vec4.ZERO; pb = new Vec4(0.5, 0, 0); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Trivial accept B", clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb)); + assertTrue(clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb), "Trivial accept B"); pa = Vec4.ZERO; pb = new Vec4(-0.5, 0, 0); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Trivial accept C", clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb)); + assertTrue(clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb), "Trivial accept C"); pa = new Vec4(.5, .5, 2); pb = new Vec4(.5, .5, -2); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Clipped at near and far", - clipped != null && clipped[0].equals(new Vec4(.5, .5, 1)) && clipped[1].equals(new Vec4(.5, .5, -1))); + assertTrue(clipped != null && clipped[0].equals(new Vec4(.5, .5, 1)) && clipped[1].equals(new Vec4(.5, .5, -1)), "Clipped at near and far"); pa = new Vec4(.5, .5, .5); pb = new Vec4(.5, .5, -.5); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Trivial accept D", clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb)); + assertTrue(clipped != null && clipped[0].equals(pa) && clipped[1].equals(pb), "Trivial accept D"); pa = new Vec4(2, 2, 2); pb = new Vec4(4, 4, 4); clipped = Line.clipToFrustum(pa, pb, f); - assertTrue("Segment not in frustum", clipped == null); + assertTrue(clipped == null, "Segment not in frustum"); } @Test @@ -85,30 +80,30 @@ public void testDistanceToPoint() Vec4 p; p = new Vec4(0, 0, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point at start of line at origin", d, 0d, 0.0); + assertEquals(d, 0d, 0.0, "Point at start of line at origin"); p = new Vec4(-2, 0, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point to left of segment on x axis", d, 2d, 0.0); + assertEquals(d, 2d, 0.0, "Point to left of segment on x axis"); p = new Vec4(3, 0, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point to right of segment on x axis", d, 1d, 0.0); + assertEquals(d, 1d, 0.0, "Point to right of segment on x axis"); p = new Vec4(2, 7, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point 7 above segment end point", d, 7d, 0.0); + assertEquals(d, 7d, 0.0, "Point 7 above segment end point"); p = new Vec4(1, 7, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point 7 above segment mid-point", d, 7d, 0.0); + assertEquals(d, 7d, 0.0, "Point 7 above segment mid-point"); p = new Vec4(1, -7, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point 7 below segment mid-point", d, 7d, 0.0); + assertEquals(d, 7d, 0.0, "Point 7 below segment mid-point"); p = new Vec4(1, 0.5, 0); d = Line.distanceToSegment(p0, p1, p); - assertEquals("Point 1/2 above segment 1/4-point", d, 0.5, 0.0); + assertEquals(d, 0.5, 0.0, "Point 1/2 above segment 1/4-point"); } } diff --git a/test/gov/nasa/worldwind/geom/MatrixTest.java b/test/gov/nasa/worldwind/geom/MatrixTest.java index b3d2fe2521..eac2b11491 100644 --- a/test/gov/nasa/worldwind/geom/MatrixTest.java +++ b/test/gov/nasa/worldwind/geom/MatrixTest.java @@ -28,15 +28,12 @@ package gov.nasa.worldwind.geom; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.Random; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class MatrixTest { private static final double EQUALITY_TOLERANCE = 1.0e-9; @@ -45,7 +42,7 @@ public class MatrixTest private Random random; - @Before + @BeforeEach public void setUp() throws Exception { // Use a random initialized with a constant seed to ensure that subsequent test executes get the same @@ -66,10 +63,10 @@ public void testInverseOfTransform() m = m.multiply(Matrix.fromRotationXYZ(Angle.fromDegrees(10), Angle.fromDegrees(20), Angle.fromDegrees(30))); Matrix mInv = m.getInverse(); - assertNotNull("Matrix inverse is null", mInv); + assertNotNull(mInv, "Matrix inverse is null"); Matrix identity = m.multiply(mInv); - assertTrue("Matrix inverse is incorrect", equals(identity, Matrix.IDENTITY, EQUALITY_TOLERANCE)); + assertTrue(equals(identity, Matrix.IDENTITY, EQUALITY_TOLERANCE), "Matrix inverse is incorrect"); } @Test @@ -82,10 +79,10 @@ public void testInverseOfRandom() random.nextDouble(), random.nextDouble(), random.nextDouble(), random.nextDouble()); Matrix mInv = m.getInverse(); - assertNotNull("Matrix inverse is null", mInv); + assertNotNull(mInv, "Matrix inverse is null"); Matrix identity = m.multiply(mInv); - assertTrue("Matrix inverse is incorrect", equals(identity, Matrix.IDENTITY, EQUALITY_TOLERANCE)); + assertTrue(equals(identity, Matrix.IDENTITY, EQUALITY_TOLERANCE), "Matrix inverse is incorrect"); } @Test @@ -111,7 +108,7 @@ public void testInverseOfSingular() m41, m42, m43, m44); Matrix mInv = m.getInverse(); - assertNull("Singular matrix should not have an inverse", mInv); + assertNull(mInv, "Singular matrix should not have an inverse"); } @Test @@ -124,7 +121,7 @@ public void testInverseOfZeroRow() random.nextDouble(), random.nextDouble(), random.nextDouble(), random.nextDouble()); Matrix mInv = m.getInverse(); - assertNull("Singular matrix should not have an inverse", mInv); + assertNull(mInv, "Singular matrix should not have an inverse"); } @Test @@ -153,10 +150,10 @@ public void testInverseOfNearSingular() m41, m42, m43, m44); Matrix mInv = m.getInverse(); - assertNotNull("Matrix inverse is null", mInv); + assertNotNull(mInv, "Matrix inverse is null"); Matrix identity = m.multiply(mInv); - assertTrue("Matrix inverse is incorrect", equals(identity, Matrix.IDENTITY, NEAR_SINGULAR_EQUALITY_TOLERANCE)); + assertTrue(equals(identity, Matrix.IDENTITY, NEAR_SINGULAR_EQUALITY_TOLERANCE), "Matrix inverse is incorrect"); } //**************************************************************// diff --git a/test/gov/nasa/worldwind/geom/PlaneTest.java b/test/gov/nasa/worldwind/geom/PlaneTest.java index 9d4b0643a4..ddd8e8cc6d 100644 --- a/test/gov/nasa/worldwind/geom/PlaneTest.java +++ b/test/gov/nasa/worldwind/geom/PlaneTest.java @@ -27,13 +27,9 @@ */ package gov.nasa.worldwind.geom; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class PlaneTest { @Test @@ -42,8 +38,8 @@ public void testSegmentIntersection() Plane p = new Plane(new Vec4(0, 0, -1, 0)); Vec4 pt = p.intersect(Vec4.ZERO, new Vec4(0, 0, -1)); - assertNotNull("Perpendicular, 0 at origin, not null", pt); - assertTrue("Perpendicular, 0 at origin, should produce intersection at origin", pt.equals(Vec4.ZERO)); + assertNotNull(pt, "Perpendicular, 0 at origin, not null"); + assertTrue(pt.equals(Vec4.ZERO), "Perpendicular, 0 at origin, should produce intersection at origin"); try { @@ -57,35 +53,30 @@ public void testSegmentIntersection() } pt = p.intersect(new Vec4(1, 0, 0), new Vec4(1, 0, 0)); - assertNotNull("Line segment is in fact a point, located on the plane, not null", pt); - assertTrue("Line segment is in fact a point, located on the plane, should produce intersection at (1, 0, 0)", - pt.equals(new Vec4(1, 0, 0))); + assertNotNull(pt, "Line segment is in fact a point, located on the plane, not null"); + assertTrue(pt.equals(new Vec4(1, 0, 0)), "Line segment is in fact a point, located on the plane, should produce intersection at (1, 0, 0)"); pt = p.intersect(new Vec4(0, 0, -1), new Vec4(0, 0, -1)); - assertNull("Line segment is in fact a point not on the plane, should produce null for no intersection", pt); + assertNull(pt, "Line segment is in fact a point not on the plane, should produce null for no intersection"); pt = p.intersect(new Vec4(0, 0, 1), new Vec4(0, 0, -1)); - assertNotNull("Perpendicular, integer end points off origin, not null", pt); - assertTrue("Perpendicular, integer end points off origin, should produce intersection at origin", - pt.equals(Vec4.ZERO)); + assertNotNull(pt, "Perpendicular, integer end points off origin, not null"); + assertTrue(pt.equals(Vec4.ZERO), "Perpendicular, integer end points off origin, should produce intersection at origin"); pt = p.intersect(new Vec4(0, 0, 0.5), new Vec4(0, 0, -0.5)); - assertNotNull("Perpendicular, non-integer end points off origin, not null", pt); - assertTrue("Perpendicular, non-integer end points off origin, should produce intersection at origin", - pt.equals(Vec4.ZERO)); + assertNotNull(pt, "Perpendicular, non-integer end points off origin, not null"); + assertTrue(pt.equals(Vec4.ZERO), "Perpendicular, non-integer end points off origin, should produce intersection at origin"); pt = p.intersect(new Vec4(0.5, 0.5, 0.5), new Vec4(-0.5, -0.5, -0.5)); - assertNotNull("Not perpendicular, non-integer end points off origin, not null", pt); - assertTrue("Not perpendicular, non-integer end points off origin, should produce intersection at origin", - pt.equals(Vec4.ZERO)); + assertNotNull(pt, "Not perpendicular, non-integer end points off origin, not null"); + assertTrue(pt.equals(Vec4.ZERO), "Not perpendicular, non-integer end points off origin, should produce intersection at origin"); pt = p.intersect(new Vec4(1, 0, 0), new Vec4(2, 0, 0)); - assertNotNull("Parallel, in plane, not null", pt); - assertTrue("Parallel, in plane, should produce intersection at origin", - pt.equals(Vec4.INFINITY)); + assertNotNull(pt, "Parallel, in plane, not null"); + assertTrue(pt.equals(Vec4.INFINITY), "Parallel, in plane, should produce intersection at origin"); pt = p.intersect(new Vec4(1, 0, 1), new Vec4(2, 0, 1)); - assertNull("Parallel, integer end points off origin, should produce null for no intersection", pt); + assertNull(pt, "Parallel, integer end points off origin, should produce null for no intersection"); } @Test @@ -95,6 +86,6 @@ public void testLineIntersection() Vec4 pt = p.intersect(new Line(new Vec4(807066.3082512334, 4864661.747666055, 4.5E7, 1.0), new Vec4(0.0, 0.0, -1.0, 0.0))); - assertNotNull("Simple intersection", pt); + assertNotNull(pt, "Simple intersection"); } } diff --git a/test/gov/nasa/worldwind/globes/EllipsoidalGlobeTest.java b/test/gov/nasa/worldwind/globes/EllipsoidalGlobeTest.java index e348fd5643..eadebc4541 100644 --- a/test/gov/nasa/worldwind/globes/EllipsoidalGlobeTest.java +++ b/test/gov/nasa/worldwind/globes/EllipsoidalGlobeTest.java @@ -28,13 +28,11 @@ package gov.nasa.worldwind.globes; import gov.nasa.worldwind.geom.*; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class EllipsoidalGlobeTest { private static final double THRESHOLD = 1.0e-1; @@ -42,13 +40,13 @@ public class EllipsoidalGlobeTest private Globe globe; - @Before + @BeforeEach public void setUp() { this.globe = new Earth(); } - @After + @AfterEach public void tearDown() { this.globe = null; @@ -59,7 +57,7 @@ public void testEquatorialRadius() { double radius = this.globe.getEquatorialRadius(); - assertEquals("Equatorial radius", radius, 6378137d, 0.0); + assertEquals(radius, 6378137d, 0.0, "Equatorial radius"); } @Test @@ -69,16 +67,15 @@ public void testGeodeticToCartesian() Vec4 vec = globe.computePointFromPosition(orig); - assertEquals("X comparision", vec.getX(), -5457021.181d, THRESHOLD); - assertEquals("Y comparision", vec.getY(), 3211203.627d, THRESHOLD); - assertEquals("Z comparision", vec.getZ(), -723039.434d, THRESHOLD); + assertEquals(vec.getX(), -5457021.181d, THRESHOLD, "X comparision"); + assertEquals(vec.getY(), 3211203.627d, THRESHOLD, "Y comparision"); + assertEquals(vec.getZ(), -723039.434d, THRESHOLD, "Z comparision"); //now convert back and compare to original Position p = globe.computePositionFromPoint(vec); - assertEquals("Latitude comparision", orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD); - assertEquals("Longitude comparision", orig.getLongitude().degrees, p.getLongitude().degrees, - THRESHOLD); - assertEquals("Height comparision", orig.getElevation(), p.getElevation(), THRESHOLD); + assertEquals(orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD, "Latitude comparision"); + assertEquals(orig.getLongitude().degrees, p.getLongitude().degrees, THRESHOLD, "Longitude comparision"); + assertEquals(orig.getElevation(), p.getElevation(), THRESHOLD, "Height comparision"); } @Test @@ -88,16 +85,15 @@ public void testGeodeticToCartesian2() Vec4 vec = globe.computePointFromPosition(orig); - assertEquals("X comparision", vec.getX(), 137419.7051d, THRESHOLD); - assertEquals("Y comparision", vec.getY(), 6354995.0149d, THRESHOLD); - assertEquals("Z comparision", vec.getZ(), 78555.6486d, THRESHOLD); + assertEquals(vec.getX(), 137419.7051d, THRESHOLD, "X comparision"); + assertEquals(vec.getY(), 6354995.0149d, THRESHOLD, "Y comparision"); + assertEquals(vec.getZ(), 78555.6486d, THRESHOLD, "Z comparision"); //now convert back and compare to original Position p = globe.computePositionFromPoint(vec); - assertEquals("Latitude comparision", orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD); - assertEquals("Longitude comparision", orig.getLongitude().degrees, p.getLongitude().degrees, - THRESHOLD); - assertEquals("Height comparision", orig.getElevation(), p.getElevation(), THRESHOLD); + assertEquals(orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD, "Latitude comparision"); + assertEquals(orig.getLongitude().degrees, p.getLongitude().degrees, THRESHOLD, "Longitude comparision"); + assertEquals(orig.getElevation(), p.getElevation(), THRESHOLD, "Height comparision"); } @Test @@ -107,16 +103,15 @@ public void testGeodeticToCartesian3() Vec4 vec = globe.computePointFromPosition(orig); - assertEquals("X comparision", vec.getX(), 1681968.3306d, THRESHOLD); - assertEquals("Y comparision", vec.getY(), -3537721.6660d, THRESHOLD); - assertEquals("Z comparision", vec.getZ(), 5025370.8202d, THRESHOLD); + assertEquals(vec.getX(), 1681968.3306d, THRESHOLD, "X comparision"); + assertEquals(vec.getY(), -3537721.6660d, THRESHOLD, "Y comparision"); + assertEquals(vec.getZ(), 5025370.8202d, THRESHOLD, "Z comparision"); //now convert back and compare to original Position p = globe.computePositionFromPoint(vec); - assertEquals("Latitude comparision", orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD); - assertEquals("Longitude comparision", orig.getLongitude().degrees, p.getLongitude().degrees, - THRESHOLD); - assertEquals("Height comparision", orig.getElevation(), p.getElevation(), THRESHOLD); + assertEquals(orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD, "Latitude comparision"); + assertEquals(orig.getLongitude().degrees, p.getLongitude().degrees, THRESHOLD, "Longitude comparision"); + assertEquals(orig.getElevation(), p.getElevation(), THRESHOLD, "Height comparision"); } @Test @@ -126,16 +121,15 @@ public void testGeodeticToCartesian4() Vec4 vec = globe.computePointFromPosition(orig); - assertEquals("X comparision", vec.getX(), 137419.705d, THRESHOLD); - assertEquals("Y comparision", vec.getY(), 6354995.001d, THRESHOLD); - assertEquals("Z comparision", vec.getZ(), 78555.649d, THRESHOLD); + assertEquals(vec.getX(), 137419.705d, THRESHOLD, "X comparision"); + assertEquals(vec.getY(), 6354995.001d, THRESHOLD, "Y comparision"); + assertEquals(vec.getZ(), 78555.649d, THRESHOLD, "Z comparision"); //now convert back and compare to original Position p = globe.computePositionFromPoint(vec); - assertEquals("Latitude comparision", orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD); - assertEquals("Longitude comparision", orig.getLongitude().degrees, p.getLongitude().degrees, - THRESHOLD); - assertEquals("Height comparision", orig.getElevation(), p.getElevation(), THRESHOLD); + assertEquals(orig.getLatitude().degrees, p.getLatitude().degrees, THRESHOLD, "Latitude comparision"); + assertEquals(orig.getLongitude().degrees, p.getLongitude().degrees, THRESHOLD, "Longitude comparision"); + assertEquals(orig.getElevation(), p.getElevation(), THRESHOLD, "Height comparision"); } @Test @@ -162,16 +156,16 @@ public void testEllipsoidEquatorialPlane() // and elevation are based on standard polar (circular) // coordinates. String msg = "At x " + x + ", and z " + z; - assertEquals(msg, Math.sqrt(x * x + z * z) - a, p.elevation, THRESHOLD); + assertEquals(Math.sqrt(x * x + z * z) - a, p.elevation, THRESHOLD, msg); //noinspection SuspiciousNameCombination - assertEquals(msg, Math.atan2(x, z), p.longitude.radians, THRESHOLD); - assertEquals(msg, 0, p.latitude.radians, THRESHOLD); + assertEquals(Math.atan2(x, z), p.longitude.radians, THRESHOLD, msg); + assertEquals(0, p.latitude.radians, THRESHOLD, msg); // Make sure round trip works Vec4 w = earth.computePointFromPosition(p); - assertEquals(msg, v.x, w.x, THRESHOLD); - assertEquals(msg, v.y, w.y, THRESHOLD); - assertEquals(msg, v.z, w.z, THRESHOLD); + assertEquals(v.x, w.x, THRESHOLD, msg); + assertEquals(v.y, w.y, THRESHOLD, msg); + assertEquals(v.z, w.z, THRESHOLD, msg); } } @@ -195,15 +189,15 @@ public void testEllipsoidEquatorialPlane() Vec4 v = earth.computePointFromPosition(p); String msg = "At longitude " + lon + ", radius " + r; - assertEquals(msg, 0, v.y, THRESHOLD); - assertEquals(msg, r * Math.sin(lon), v.x, THRESHOLD); - assertEquals(msg, r * Math.cos(lon), v.z, THRESHOLD); + assertEquals(0, v.y, THRESHOLD, msg); + assertEquals(r * Math.sin(lon), v.x, THRESHOLD, msg); + assertEquals(r * Math.cos(lon), v.z, THRESHOLD, msg); // Make sure round trip works Position q = earth.computePositionFromPoint(v); - assertEquals(msg, p.latitude.radians, q.latitude.radians, THRESHOLD); - assertEquals(msg, p.longitude.radians, q.longitude.radians, THRESHOLD); - assertEquals(msg, p.elevation, q.elevation, THRESHOLD); + assertEquals(p.latitude.radians, q.latitude.radians, THRESHOLD, msg); + assertEquals(p.longitude.radians, q.longitude.radians, THRESHOLD, msg); + assertEquals(p.elevation, q.elevation, THRESHOLD, msg); } } } @@ -228,15 +222,15 @@ public void testEllipsoidAxis() Position p = earth.computePositionFromPoint(v); // Longitude is unspecifiable along the axis - assertEquals(msg, Math.PI / 2 * Math.signum(y), p.latitude.radians, THRESHOLD); + assertEquals(Math.PI / 2 * Math.signum(y), p.latitude.radians, THRESHOLD, msg); // System.out.println("Relative error at y=\t"+y+"\t"+((Math.abs(y)-b)/(p.elevation))); - assertEquals(msg, Math.abs(y) - b, p.elevation, THRESHOLD); + assertEquals(Math.abs(y) - b, p.elevation, THRESHOLD, msg); // Check geodetic->cartesian Vec4 w = earth.computePointFromPosition(p); - assertEquals(msg, v.x, w.x, THRESHOLD); - assertEquals(msg, v.y, w.y, THRESHOLD); - assertEquals(msg, v.z, w.z, THRESHOLD); + assertEquals(v.x, w.x, THRESHOLD, msg); + assertEquals(v.y, w.y, THRESHOLD, msg); + assertEquals(v.z, w.z, THRESHOLD, msg); } } @@ -257,7 +251,7 @@ public void testEllipsoidCenter() // assertEquals(-earth.getEquatorialRadius(), p.elevation, THRESHOLD); // assertEquals(0, p.latitude.radians, THRESHOLD); // case b: center considered as part of the axis - assertEquals("At center", -earth.getPolarRadius(), p.elevation, THRESHOLD); + assertEquals(-earth.getPolarRadius(), p.elevation, THRESHOLD, "At center"); // case b1: part of northern axis // assertEquals(Math.PI/2, p.latitude.radians, THRESHOLD); // case b2: part of southern axis @@ -293,13 +287,13 @@ public void testGeneralRoundTripCartesianConversion() Position p = earth.computePositionFromPoint(new Vec4(x, y, z)); String msg = "At [x, y, z]=[" + x + ", " + y + ", " + z + "]"; // Check continuity - assertEquals(msg, Math.signum(y), Math.signum(p.latitude.degrees), THRESHOLD); + assertEquals(Math.signum(y), Math.signum(p.latitude.degrees), THRESHOLD, msg); Vec4 v = earth.computePointFromPosition(p); // Check consistency - assertEquals(msg, x, v.x, THRESHOLD); - assertEquals(msg, y, v.y, THRESHOLD); - assertEquals(msg, z, v.z, THRESHOLD); + assertEquals(x, v.x, THRESHOLD, msg); + assertEquals(y, v.y, THRESHOLD, msg); + assertEquals(z, v.z, THRESHOLD, msg); } } } @@ -331,13 +325,13 @@ public void testRoundTripCartesianConversionAtEvolute() Position pos = earth.computePositionFromPoint(new Vec4(x, y, 0)); // Check continuity - assertEquals(msg, Math.signum(y), Math.signum(pos.latitude.degrees), THRESHOLD); + assertEquals(Math.signum(y), Math.signum(pos.latitude.degrees), THRESHOLD, msg); Vec4 w = earth.computePointFromPosition(pos); // Check consistency - assertEquals(msg, x, w.x, THRESHOLD); - assertEquals(msg, y, w.y, THRESHOLD); - assertEquals(msg, 0, w.z, THRESHOLD); + assertEquals(x, w.x, THRESHOLD, msg); + assertEquals(y, w.y, THRESHOLD, msg); + assertEquals(0, w.z, THRESHOLD, msg); } } } diff --git a/test/gov/nasa/worldwind/layers/AnnotationLayerTest.java b/test/gov/nasa/worldwind/layers/AnnotationLayerTest.java index bbe2ef8a4b..58a71917f7 100644 --- a/test/gov/nasa/worldwind/layers/AnnotationLayerTest.java +++ b/test/gov/nasa/worldwind/layers/AnnotationLayerTest.java @@ -31,15 +31,11 @@ import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.render.*; import gov.nasa.worldwind.view.orbit.BasicOrbitView; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.util.Iterator; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class AnnotationLayerTest { ////////////////////////////////////////////////////////// @@ -53,7 +49,7 @@ public void testConstructor() // Test the parameterless constructor. layer = new AnnotationLayer(); - assertNotNull("", layer); + assertNotNull(layer, ""); } @Test @@ -68,7 +64,7 @@ public void testAddAnnotation() } // Test that the layer contains the annotations. - assertEquals("", annotations, layer.getAnnotations()); + assertIterablesEqual(annotations, layer.getAnnotations(), ""); } @Test @@ -80,7 +76,7 @@ public void testAddAnnotations() layer.addAnnotations(annotations); // Test that the layer contains the annotations. - assertEquals("", annotations, layer.getAnnotations()); + assertIterablesEqual(annotations, layer.getAnnotations(), ""); } @Test @@ -99,7 +95,7 @@ public void testRemoveAnnotation() } // Test that the layer contains no annotations. - assertFalse("", layer.getAnnotations().iterator().hasNext()); + assertFalse(layer.getAnnotations().iterator().hasNext(), ""); } @Test @@ -112,7 +108,7 @@ public void testRemoveAllAnnotations() layer.removeAllAnnotations(); // Test that the layer contains no annotations. - assertFalse("", layer.getAnnotations().iterator().hasNext()); + assertFalse(layer.getAnnotations().iterator().hasNext(), ""); } @Test @@ -124,7 +120,7 @@ public void testSetAnnotations() layer.setAnnotations(annotations); // Test that the layer points to the Iterable. - assertSame("", annotations, layer.getAnnotations()); + assertSame(annotations, layer.getAnnotations(), ""); } ////////////////////////////////////////////////////////// @@ -142,9 +138,9 @@ public void testSetAnnotationsClearsAnnotations() layer.setAnnotations(null); // Test that the layer does not point to the Iterable. - assertNotSame("", annotations, layer.getAnnotations()); + assertNotSame(annotations, layer.getAnnotations(), ""); // Test that the layer contains no annotations. - assertFalse("", layer.getAnnotations().iterator().hasNext()); + assertFalse(layer.getAnnotations().iterator().hasNext(), ""); } @Test @@ -158,9 +154,9 @@ public void testSetAnnotationsThenAddAnnotations() layer.addAnnotations(annotations); // Test that the layer does not point to the Iterable. - assertNotSame("", annotations, layer.getAnnotations()); + assertNotSame(annotations, layer.getAnnotations(), ""); // Test that the layer contains the annotations. - assertEquals("", annotations, layer.getAnnotations()); + assertIterablesEqual(annotations, layer.getAnnotations(), ""); } @Test @@ -191,13 +187,13 @@ public void testMaliciousGetAnnotations() } } } - catch (UnsupportedOperationException e) + catch (UnsupportedOperationException ignored) { - e.printStackTrace(); + // An immutable view is acceptable — what matters is that layer state is unchanged below. } // Test that the layer contents do not change, even if the returned list can be modified. - assertEquals("", annotations, layerAnnotations); + assertIterablesEqual(annotations, layerAnnotations, ""); } @Test @@ -237,16 +233,8 @@ public void testAddAnnotationFail() AnnotationLayer layer = new AnnotationLayer(); layer.setAnnotations(annotations); - try - { - // Expecting an IllegalStateException here. - layer.addAnnotation(new GlobeAnnotation("", Position.ZERO)); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, + () -> layer.addAnnotation(new GlobeAnnotation("", Position.ZERO))); } @Test @@ -257,16 +245,7 @@ public void testAddAnnotationsFail() AnnotationLayer layer = new AnnotationLayer(); layer.setAnnotations(annotations); - try - { - // Expecting an IllegalStateException here. - layer.addAnnotations(annotations); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.addAnnotations(annotations)); } @Test @@ -277,16 +256,8 @@ public void testRemoveAnnotationFail() AnnotationLayer layer = new AnnotationLayer(); layer.setAnnotations(annotations); - try - { - // Expecting an IllegalStateException here. - layer.removeAnnotation(new GlobeAnnotation("", Position.ZERO)); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, + () -> layer.removeAnnotation(new GlobeAnnotation("", Position.ZERO))); } @Test @@ -297,16 +268,7 @@ public void testRemoveAllAnnotationsFail() AnnotationLayer layer = new AnnotationLayer(); layer.setAnnotations(annotations); - try - { - // Expecting an IllegalStateException here. - layer.removeAllAnnotations(); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.removeAllAnnotations()); } ////////////////////////////////////////////////////////// @@ -314,11 +276,11 @@ public void testRemoveAllAnnotationsFail() ////////////////////////////////////////////////////////// @SuppressWarnings({"JavaDoc"}) - private static void assertEquals(String message, Iterable expected, Iterable actual) + private static void assertIterablesEqual(Iterable expected, Iterable actual, String message) { if (expected == null) { - assertNull(message, actual); + assertNull(actual, message); } else { @@ -326,10 +288,10 @@ private static void assertEquals(String message, Iterable expected, // Compare the elements in each iterator, as long as they both have elements. while (expectedIter.hasNext() && actualIter.hasNext()) { - Assert.assertEquals(message, expectedIter.next(), actualIter.next()); + assertEquals(expectedIter.next(), actualIter.next(), message); } // If either iterator has more elements, then their lengths are different. - assertFalse(message, expectedIter.hasNext() || actualIter.hasNext()); + assertFalse(expectedIter.hasNext() || actualIter.hasNext(), message); } } diff --git a/test/gov/nasa/worldwind/layers/IconLayerTest.java b/test/gov/nasa/worldwind/layers/IconLayerTest.java index 13de4be8f7..bdc1e694ae 100644 --- a/test/gov/nasa/worldwind/layers/IconLayerTest.java +++ b/test/gov/nasa/worldwind/layers/IconLayerTest.java @@ -31,15 +31,11 @@ import gov.nasa.worldwind.geom.Position; import gov.nasa.worldwind.render.*; import gov.nasa.worldwind.view.orbit.BasicOrbitView; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class IconLayerTest { ////////////////////////////////////////////////////////// @@ -53,7 +49,7 @@ public void testConstructor() // Test the parameterless constructor. layer = new IconLayer(); - assertNotNull("", layer); + assertNotNull(layer, ""); } @Test @@ -68,7 +64,7 @@ public void testAddIcon() } // Test that the layer contains the icons. - assertEquals("", icons, layer.getIcons()); + assertIterablesEqual(icons, layer.getIcons(), ""); } @Test @@ -80,7 +76,7 @@ public void testAddIcons() layer.addIcons(icons); // Test that the layer contains the icons. - assertEquals("", icons, layer.getIcons()); + assertIterablesEqual(icons, layer.getIcons(), ""); } @Test @@ -99,7 +95,7 @@ public void testRemoveIcon() } // Test that the layer contains no icons. - assertFalse("", layer.getIcons().iterator().hasNext()); + assertFalse(layer.getIcons().iterator().hasNext(), ""); } @Test @@ -112,7 +108,7 @@ public void testRemoveAllIcons() layer.removeAllIcons(); // Test that the layer contains no icons. - assertFalse("", layer.getIcons().iterator().hasNext()); + assertFalse(layer.getIcons().iterator().hasNext(), ""); } @Test @@ -124,7 +120,7 @@ public void testSetIcons() layer.setIcons(icons); // Test that the layer points to the Iterable. - assertSame("", icons, layer.getIcons()); + assertSame(icons, layer.getIcons(), ""); } ////////////////////////////////////////////////////////// @@ -142,9 +138,9 @@ public void testSetIconsClearsIcons() layer.setIcons(null); // Test that the layer does not point to the Iterable. - assertNotSame("", icons, layer.getIcons()); + assertNotSame(icons, layer.getIcons(), ""); // Test that the layer contains no icons. - assertFalse("", layer.getIcons().iterator().hasNext()); + assertFalse(layer.getIcons().iterator().hasNext(), ""); } @Test @@ -158,9 +154,9 @@ public void testSetIconsThenAddIcons() layer.addIcons(icons); // Test that the layer does not point to the Iterable. - assertNotSame("", icons, layer.getIcons()); + assertNotSame(icons, layer.getIcons(), ""); // Test that the layer contains the icons. - assertEquals("", icons, layer.getIcons()); + assertIterablesEqual(icons, layer.getIcons(), ""); } @Test @@ -191,13 +187,13 @@ public void testMaliciousGetIcons() } } } - catch (UnsupportedOperationException e) + catch (UnsupportedOperationException ignored) { - e.printStackTrace(); + // An immutable view is acceptable — what matters is that layer state is unchanged below. } // Test that the layer contents do not change, even if the returned list can be modified. - assertEquals("", icons, layerIcons); + assertIterablesEqual(icons, layerIcons, ""); } @Test @@ -237,16 +233,8 @@ public void testAddIconFail() IconLayer layer = new IconLayer(); layer.setIcons(icons); - try - { - // Expecting an IllegalStateException here. - layer.addIcon(new UserFacingIcon("", Position.ZERO)); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, + () -> layer.addIcon(new UserFacingIcon("", Position.ZERO))); } @Test @@ -257,16 +245,7 @@ public void testAddIconsFail() IconLayer layer = new IconLayer(); layer.setIcons(icons); - try - { - // Expecting an IllegalStateException here. - layer.addIcons(icons); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.addIcons(icons)); } @Test @@ -277,16 +256,8 @@ public void testRemoveIconFail() IconLayer layer = new IconLayer(); layer.setIcons(icons); - try - { - // Expecting an IllegalStateException here. - layer.removeIcon(new UserFacingIcon("", Position.ZERO)); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, + () -> layer.removeIcon(new UserFacingIcon("", Position.ZERO))); } @Test @@ -297,16 +268,7 @@ public void testRemoveAllIconsFail() IconLayer layer = new IconLayer(); layer.setIcons(icons); - try - { - // Expecting an IllegalStateException here. - layer.removeAllIcons(); - fail(""); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.removeAllIcons()); } ////////////////////////////////////////////////////////// @@ -314,11 +276,11 @@ public void testRemoveAllIconsFail() ////////////////////////////////////////////////////////// @SuppressWarnings({"JavaDoc"}) - private static void assertEquals(String message, Iterable expected, Iterable actual) + private static void assertIterablesEqual(Iterable expected, Iterable actual, String message) { if (expected == null) { - assertNull(message, actual); + assertNull(actual, message); } else { diff --git a/test/gov/nasa/worldwind/layers/RenderableLayerTest.java b/test/gov/nasa/worldwind/layers/RenderableLayerTest.java index b90e7ab5ec..32d2e4875b 100644 --- a/test/gov/nasa/worldwind/layers/RenderableLayerTest.java +++ b/test/gov/nasa/worldwind/layers/RenderableLayerTest.java @@ -30,15 +30,11 @@ import gov.nasa.worldwind.BasicModel; import gov.nasa.worldwind.render.*; import gov.nasa.worldwind.view.orbit.BasicOrbitView; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class RenderableLayerTest { ////////////////////////////////////////////////////////// @@ -52,7 +48,7 @@ public void testConstructor() // Test the parameterless constructor. layer = new RenderableLayer(); - assertNotNull("", layer); + assertNotNull(layer, ""); } @Test @@ -67,7 +63,7 @@ public void testAddRenderable() } // Test that the layer contains the renderables. - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -79,7 +75,7 @@ public void testAddRenderables() layer.addRenderables(renderables); // Test that the layer contains the renderables. - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -96,7 +92,7 @@ public void testInsertRenderable() layer.addRenderable(layer.getNumRenderables(), renderable); } - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -113,7 +109,7 @@ public void testInsertRenderableAtBeginning() renderables.add(0, inserted); layer.addRenderable(0, inserted); - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -130,7 +126,7 @@ public void testInsertRenderableAfterFirst() renderables.add(1, inserted); layer.addRenderable(1, inserted); - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -147,7 +143,7 @@ public void testInsertRenderableAtEnd() renderables.add(renderables.size(), inserted); layer.addRenderable(layer.getNumRenderables(), inserted); - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -166,7 +162,7 @@ public void testRemoveRenderable() } // Test that the layer contains no renderables. - assertFalse("", layer.getRenderables().iterator().hasNext()); + assertFalse(layer.getRenderables().iterator().hasNext(), ""); } @Test @@ -179,7 +175,7 @@ public void testRemoveAllRenderables() layer.removeAllRenderables(); // Test that the layer contains no renderables. - assertFalse("", layer.getRenderables().iterator().hasNext()); + assertFalse(layer.getRenderables().iterator().hasNext(), ""); } @Test @@ -191,7 +187,7 @@ public void testSetRenderables() layer.setRenderables(renderables); // Test that the layer points to the Iterable. - assertSame("", renderables, layer.getRenderables()); + assertSame(renderables, layer.getRenderables(), ""); } ////////////////////////////////////////////////////////// @@ -209,9 +205,9 @@ public void testSetRenderablesClearsRenderables() layer.setRenderables(null); // Test that the layer does not point to the Iterable. - assertNotSame("", renderables, layer.getRenderables()); + assertNotSame(renderables, layer.getRenderables(), ""); // Test that the layer contains no renderables. - assertFalse("", layer.getRenderables().iterator().hasNext()); + assertFalse(layer.getRenderables().iterator().hasNext(), ""); } @Test @@ -225,9 +221,9 @@ public void testSetRenderablesThenAddRenderables() layer.addRenderables(renderables); // Test that the layer does not point to the Iterable. - assertNotSame("", renderables, layer.getRenderables()); + assertNotSame(renderables, layer.getRenderables(), ""); // Test that the layer contains the renderables. - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -258,13 +254,13 @@ public void testMaliciousGetRenderables() } } } - catch (UnsupportedOperationException e) + catch (UnsupportedOperationException ignored) { - e.printStackTrace(); + // An immutable view is acceptable — what matters is that layer state is unchanged below. } // Test that the layer contents do not change, even if the returned list can be modified. - assertEquals("", renderables, layer.getRenderables()); + assertIterablesEqual(renderables, layer.getRenderables(), ""); } @Test @@ -303,7 +299,7 @@ public void testDisposeDoesNotClearRenderables() layer.dispose(); // Test that the layer contains the renderables. - assertEquals("", emptyRenderables, layer.getRenderables()); + assertIterablesEqual(emptyRenderables, layer.getRenderables(), ""); } ////////////////////////////////////////////////////////// @@ -318,16 +314,7 @@ public void testAddRenderableFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.addRenderable(new Path()); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.addRenderable(new Path())); } @Test @@ -338,16 +325,7 @@ public void testAddRenderablesFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.addRenderables(renderables); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.addRenderables(renderables)); } @Test @@ -358,16 +336,7 @@ public void testInsertRenderableFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.addRenderable(0, new Path()); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.addRenderable(0, new Path())); } @Test @@ -378,16 +347,7 @@ public void testRemoveRenderableFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.removeRenderable(new Path()); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.removeRenderable(new Path())); } @Test @@ -398,16 +358,7 @@ public void testRemoveAllRenderablesFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.removeAllRenderables(); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.removeAllRenderables()); } @Test @@ -418,27 +369,18 @@ public void testDisposeFail() RenderableLayer layer = new RenderableLayer(); layer.setRenderables(renderables); - try - { - // Expecting an IllegalStateException here. - layer.dispose(); - fail("Should raise an IllegalStateException"); - } - catch (IllegalStateException e) - { - e.printStackTrace(); - } + assertThrows(IllegalStateException.class, () -> layer.dispose()); } ////////////////////////////////////////////////////////// // Helper Methods ////////////////////////////////////////////////////////// - private static void assertEquals(String message, Iterable expected, Iterable actual) + private static void assertIterablesEqual(Iterable expected, Iterable actual, String message) { if (expected == null) { - assertNull(message, actual); + assertNull(actual, message); } else { @@ -446,10 +388,10 @@ private static void assertEquals(String message, Iterable expected, // Compare the elements in each iterator, as long as they both have elements. while (expectedIter.hasNext() && actualIter.hasNext()) { - Assert.assertEquals(message, expectedIter.next(), actualIter.next()); + assertEquals(expectedIter.next(), actualIter.next(), message); } // If either iterator has more elements, then their lengths are different. - assertFalse(message, expectedIter.hasNext() || actualIter.hasNext()); + assertFalse(expectedIter.hasNext() || actualIter.hasNext(), message); } } diff --git a/test/gov/nasa/worldwind/ogc/collada/ColladaAccessorTest.java b/test/gov/nasa/worldwind/ogc/collada/ColladaAccessorTest.java index 21d678cad5..498fcfd4dc 100644 --- a/test/gov/nasa/worldwind/ogc/collada/ColladaAccessorTest.java +++ b/test/gov/nasa/worldwind/ogc/collada/ColladaAccessorTest.java @@ -29,16 +29,12 @@ package gov.nasa.worldwind.ogc.collada; import gov.nasa.worldwind.util.WWIO; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.io.IOException; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class ColladaAccessorTest { @Test diff --git a/test/gov/nasa/worldwind/ogc/kml/KMLExportTest.java b/test/gov/nasa/worldwind/ogc/kml/KMLExportTest.java index 426e715440..7e16416c7d 100644 --- a/test/gov/nasa/worldwind/ogc/kml/KMLExportTest.java +++ b/test/gov/nasa/worldwind/ogc/kml/KMLExportTest.java @@ -2,25 +2,25 @@ * Copyright 2006-2009, 2017, 2020 United States Government, as represented by the * Administrator of the National Aeronautics and Space Administration. * All rights reserved. - * + * * The NASA World Wind Java (WWJ) platform is licensed under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * + * * NASA World Wind Java (WWJ) also contains the following 3rd party Open Source * software: - * + * * Jackson Parser – Licensed under Apache 2.0 * GDAL – Licensed under MIT * JOGL – Licensed under Berkeley Software Distribution (BSD) * Gluegen – Licensed under Berkeley Software Distribution (BSD) - * + * * A complete listing of 3rd Party software notices and licenses included in * NASA World Wind Java (WWJ) can be found in the WorldWindJava-v2.2 3rd-party * notices and licenses PDF found in code directory. @@ -33,9 +33,10 @@ import gov.nasa.worldwind.render.*; import gov.nasa.worldwind.util.Logging; import gov.nasa.worldwindx.examples.kml.KMLDocumentBuilder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import javax.xml.XMLConstants; import javax.xml.stream.XMLStreamException; @@ -44,32 +45,20 @@ import javax.xml.validation.*; import java.io.*; import java.util.*; +import java.util.stream.Stream; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * Test export of KML by writing shapes to KML and validating the resulting document against the KML schema. */ -@RunWith(Parameterized.class) public class KMLExportTest { private static ShapeAttributes normalShapeAttributes; private static ShapeAttributes highlightShapeAttributes; - private List objectsToExport; - - public KMLExportTest(List objectsToExport) - { - this.objectsToExport = objectsToExport; - } - - /** - * Method to create parametrized data to drive the test. - * - * @return Collection of object[]. Each object[] holds parameters for one invocation of the test. - */ - @Parameterized.Parameters - public static Collection data() + @BeforeAll + static void setupAttributes() { normalShapeAttributes = new BasicShapeAttributes(); normalShapeAttributes.setInteriorMaterial(Material.BLUE); @@ -78,21 +67,27 @@ public static Collection data() highlightShapeAttributes = new BasicShapeAttributes(); highlightShapeAttributes.setInteriorMaterial(Material.RED); highlightShapeAttributes.setOutlineMaterial(Material.BLACK); + } - return Arrays.asList(new Object[][] { + /** + * Provides parameterised data: one {@code List} per test invocation. + */ + static Stream> data() + { + return Stream.of( // Export a single instance of each type of shape to its own document to test the shape exporters in isolation. - {Collections.singletonList(makePointPlacemark())}, - {Collections.singletonList(makePath())}, - {Collections.singletonList(makePolygon())}, - {Collections.singletonList(makeExtrudedPolygon())}, - {Collections.singletonList(makeSurfacePolygon())}, - {Collections.singletonList(makeScreenImage())}, - {Collections.singletonList(makeSurfaceSector())}, - {Collections.singletonList(makeSurfacePolyline())}, - {Collections.singletonList(makeSurfaceImage())}, - {Collections.singletonList(makeSurfaceImageWithLatLonQuad())}, + Collections.singletonList(makePointPlacemark()), + Collections.singletonList(makePath()), + Collections.singletonList(makePolygon()), + Collections.singletonList(makeExtrudedPolygon()), + Collections.singletonList(makeSurfacePolygon()), + Collections.singletonList(makeScreenImage()), + Collections.singletonList(makeSurfaceSector()), + Collections.singletonList(makeSurfacePolyline()), + Collections.singletonList(makeSurfaceImage()), + Collections.singletonList(makeSurfaceImageWithLatLonQuad()), // Finally, test exporting all of the shapes to the same document. - {Arrays.asList(makePointPlacemark(), + Arrays.asList(makePointPlacemark(), makePath(), makePolygon(), makeExtrudedPolygon(), @@ -101,17 +96,18 @@ public static Collection data() makeSurfaceSector(), makeSurfacePolyline(), makeSurfaceImage(), - makeSurfaceImageWithLatLonQuad())} - }); + makeSurfaceImageWithLatLonQuad()) + ); } - @Test - public void testExport() throws XMLStreamException, IOException + @ParameterizedTest + @MethodSource("data") + public void testExport(List objectsToExport) throws XMLStreamException, IOException { Writer stringWriter = new StringWriter(); KMLDocumentBuilder kmlBuilder = new KMLDocumentBuilder(stringWriter); - for (Exportable e : this.objectsToExport) + for (Exportable e : objectsToExport) { kmlBuilder.writeObject(e); } @@ -120,14 +116,16 @@ public void testExport() throws XMLStreamException, IOException String xmlString = stringWriter.toString(); boolean docValid = validateDocument(xmlString); - assertTrue("Exported document failed to validate", docValid); + assertTrue(docValid, "Exported document failed to validate"); } - @Test(expected = UnsupportedOperationException.class) - public void testKmlNotSupported() throws XMLStreamException, IOException + @Test + public void testKmlNotSupported() { - Pyramid pyramid = new Pyramid(Position.ZERO, 100, 100); - pyramid.export(KMLConstants.KML_MIME_TYPE, new StringWriter()); + assertThrows(UnsupportedOperationException.class, () -> { + Pyramid pyramid = new Pyramid(Position.ZERO, 100, 100); + pyramid.export(KMLConstants.KML_MIME_TYPE, new StringWriter()); + }); } private boolean validateDocument(String doc) diff --git a/test/gov/nasa/worldwind/ogc/kml/KMLReferenceTest.java b/test/gov/nasa/worldwind/ogc/kml/KMLReferenceTest.java index 41c200b6ff..76d92333f7 100644 --- a/test/gov/nasa/worldwind/ogc/kml/KMLReferenceTest.java +++ b/test/gov/nasa/worldwind/ogc/kml/KMLReferenceTest.java @@ -28,24 +28,24 @@ package gov.nasa.worldwind.ogc.kml; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.io.IOException; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; /** * Test resolution of local and remote references using {@link KMLRoot#resolveReference(String)}. */ -@RunWith(JUnit4.class) public class KMLReferenceTest { private KMLRoot root; - @Before + @BeforeEach public void setUp() { try @@ -58,7 +58,7 @@ public void setUp() } } - @After + @AfterEach public void tearDown() { this.root = null; @@ -68,20 +68,20 @@ public void tearDown() public void testReferenceToLocalKMLFile() { Object o = this.root.resolveReference("testData/KML/PointPlacemark.kml"); - assertTrue("Cannot resolve reference to local KML file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to local KML file"); o = this.root.resolveLocalReference("testData/KML/PointPlacemark.kml", null); - assertTrue("Cannot resolve reference to local KML file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to local KML file"); } @Test public void testReferenceToLocalKMZFile() { Object o = this.root.resolveReference("testData/KML/PointPlacemarkLocalImage.kmz"); - assertTrue("Cannot resolve reference to local KML file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to local KML file"); o = this.root.resolveLocalReference("testData/KML/PointPlacemarkLocalImage.kmz", null); - assertTrue("Cannot resolve reference to local KML file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to local KML file"); } @Test @@ -89,32 +89,32 @@ public void testReferenceToLocalImage() { String path = "testData/KML/etna.jpg"; Object o = this.root.resolveReference(path); - assertEquals("Cannot resolve reference to local image file", path, o); + assertEquals(path, o, "Cannot resolve reference to local image file"); o = this.root.resolveLocalReference(path, null); - assertEquals("Cannot resolve reference to local image file", path, o); + assertEquals(path, o, "Cannot resolve reference to local image file"); } @Test public void testReferenceToLocalElement() { Object o = this.root.resolveReference("#normalPlacemark"); - assertTrue("Cannot resolve reference to local style", o instanceof KMLStyle); + assertTrue(o instanceof KMLStyle, "Cannot resolve reference to local style"); // Local references should start with #, but many files do not include the #. Test that resolution works even // if the reference is malformed. o = this.root.resolveReference("normalPlacemark"); - assertTrue("Cannot resolve reference to local style (without leading #)", o instanceof KMLStyle); + assertTrue(o instanceof KMLStyle, "Cannot resolve reference to local style (without leading #)"); } @Test public void testReferenceToElementInLocalFile() { Object o = this.root.resolveReference("testData/KML/StyleReferences.kml#transBluePoly"); - assertTrue("Cannot resolve reference to element in local KML file", o instanceof KMLStyle); + assertTrue(o instanceof KMLStyle, "Cannot resolve reference to element in local KML file"); o = this.root.resolveLocalReference("testData/KML/StyleReferences.kml", "transBluePoly"); - assertTrue("Cannot resolve reference to element in local KML file", o instanceof KMLStyle); + assertTrue(o instanceof KMLStyle, "Cannot resolve reference to element in local KML file"); } @Test @@ -123,47 +123,47 @@ public void testKMZReference() throws IOException, XMLStreamException KMLRoot root = KMLRoot.createAndParse("testData/KML/PointPlacemarkLocalImage.kmz"); Object o = root.resolveReference("icon21.png"); - assertNotNull("Cannot resolve reference to file KMZ archive", o); + assertNotNull(o, "Cannot resolve reference to file KMZ archive"); } - @Ignore + @Disabled @Test public void testReferenceToRemoteKML() { String url = "https://worldwind.arc.nasa.gov/kml-samples/morekml/Network_Links/Targets/Network_Links.Targets.Simple.kml"; Object o = this.resolveReferenceBlocking(this.root, url); - assertTrue("Cannot resolve reference to remote KML file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to remote KML file"); } - @Ignore + @Disabled @Test public void testReferenceToRemoteKMZ() { String url = "https://worldwind.arc.nasa.gov/kml-samples/kml/kmz/simple/mimetype.kmz"; Object o = this.resolveReferenceBlocking(this.root, url); - assertTrue("Cannot resolve reference to remote KMZ file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to remote KMZ file"); o = this.resolveRemoteReferenceBlocking(this.root, url, null); - assertTrue("Cannot resolve reference to remote KMZ file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to remote KMZ file"); o = this.resolveNetworkLinkBlocking(this.root, url); - assertTrue("Cannot resolve reference to remote KMZ file", o instanceof KMLRoot); + assertTrue(o instanceof KMLRoot, "Cannot resolve reference to remote KMZ file"); } - @Ignore + @Disabled @Test public void testReferenceToRemoteElement() { String url = "https://worldwind.arc.nasa.gov/kml-samples/morekml/Network_Links/Targets/Network_Links.Targets.Simple.kml#networkLinkPlacemark"; Object o = this.resolveReferenceBlocking(this.root, url); - assertTrue("Cannot resolve reference to remote KML file", o instanceof KMLPlacemark); + assertTrue(o instanceof KMLPlacemark, "Cannot resolve reference to remote KML file"); o = this.resolveRemoteReferenceBlocking(this.root, "https://worldwind.arc.nasa.gov/kml-samples/morekml/Network_Links/Targets/Network_Links.Targets.Simple.kml", "networkLinkPlacemark"); - assertTrue("Cannot resolve reference to remote KML file", o instanceof KMLPlacemark); + assertTrue(o instanceof KMLPlacemark, "Cannot resolve reference to remote KML file"); } /** diff --git a/test/gov/nasa/worldwind/ogc/kml/KMLTest.java b/test/gov/nasa/worldwind/ogc/kml/KMLTest.java index 8494854197..23a663a315 100644 --- a/test/gov/nasa/worldwind/ogc/kml/KMLTest.java +++ b/test/gov/nasa/worldwind/ogc/kml/KMLTest.java @@ -35,17 +35,13 @@ import gov.nasa.worldwind.util.xml.*; import gov.nasa.worldwind.util.xml.atom.AtomConstants; import gov.nasa.worldwind.util.xml.xal.XALConstants; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.io.*; import java.net.URL; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class KMLTest { @Test @@ -56,8 +52,8 @@ public void testRootElement() KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); - assertNull("KML root hint is not null", root.getHint()); + assertNotNull(root, "KML root is null"); + assertNull(root.getHint(), "KML root hint is not null"); } @Test @@ -69,8 +65,8 @@ public void testRootHint() KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); - assertNotNull("KML root hint is null", root.getHint()); + assertNotNull(root, "KML root is null"); + assertNotNull(root.getHint(), "KML root hint is null"); } @Test @@ -84,12 +80,12 @@ public void testAbstractObjectAttributes() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLDocument); - assertEquals("Object ID not as expected", feature.getId(), ID); - assertEquals("Target ID not as expected", feature.getTargetId(), targetID); + assertTrue(feature instanceof KMLDocument, "Root feature is not as expected"); + assertEquals(feature.getId(), ID, "Object ID not as expected"); + assertEquals(feature.getTargetId(), targetID, "Target ID not as expected"); } @Test @@ -101,13 +97,13 @@ public void testUnassignedAbstractObjectAttributes() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLDocument); + assertTrue(feature instanceof KMLDocument, "Root feature is not as expected"); - assertNull("ID not null", feature.getId()); - assertNull("Target ID not null", feature.getTargetId()); + assertNull(feature.getId(), "ID not null"); + assertNull(feature.getTargetId(), "Target ID not null"); } @SuppressWarnings({"ConstantConditions"}) @@ -175,32 +171,32 @@ public void testAbstractFeatureAttributes() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLDocument); - - assertEquals("Name not as expected", feature.getName(), name); - assertEquals("Visibility not as expected", feature.getVisibility(), visibility); - assertEquals("Open not as expected", feature.getOpen(), open); - assertEquals("Address not as expected", feature.getAddress(), address); - assertEquals("Phone number not as expected", feature.getPhoneNumber(), phoneNumber); - assertEquals("Snippet not as expected", feature.getSnippet(), snippet); - assertEquals("Description not as expected", feature.getDescription(), description); - assertEquals("Style URL not as expected", feature.getStyleUrl().getCharacters(), styleUrl); - - assertEquals("Link href not as expected", feature.getLink().getHref(), linkHref); - assertEquals("Link rel not as expected", feature.getLink().getRel(), linkRel); - assertEquals("Link type not as expected", feature.getLink().getType(), linkType); - assertEquals("Link hreflang not as expected", feature.getLink().getHreflang(), linkHreflang); - assertEquals("Link title not as expected", feature.getLink().getTitle(), linkTitle); - assertEquals("Link length not as expected", feature.getLink().getLength().intValue(), linkLength); - assertEquals("Link base not as expected", feature.getLink().getBase(), linkBase); - assertEquals("Link lang not as expected", feature.getLink().getLang(), linkLang); - - assertEquals("Author name not as expected", feature.getAuthor().getName(), authorName); - assertEquals("Author email not as expected", feature.getAuthor().getEmail(), authorEmail); - assertEquals("Author URI not as expected", feature.getAuthor().getUri(), authorUri); + assertTrue(feature instanceof KMLDocument, "Root feature is not as expected"); + + assertEquals(feature.getName(), name, "Name not as expected"); + assertEquals(feature.getVisibility(), visibility, "Visibility not as expected"); + assertEquals(feature.getOpen(), open, "Open not as expected"); + assertEquals(feature.getAddress(), address, "Address not as expected"); + assertEquals(feature.getPhoneNumber(), phoneNumber, "Phone number not as expected"); + assertEquals(feature.getSnippet(), snippet, "Snippet not as expected"); + assertEquals(feature.getDescription(), description, "Description not as expected"); + assertEquals(feature.getStyleUrl().getCharacters(), styleUrl, "Style URL not as expected"); + + assertEquals(feature.getLink().getHref(), linkHref, "Link href not as expected"); + assertEquals(feature.getLink().getRel(), linkRel, "Link rel not as expected"); + assertEquals(feature.getLink().getType(), linkType, "Link type not as expected"); + assertEquals(feature.getLink().getHreflang(), linkHreflang, "Link hreflang not as expected"); + assertEquals(feature.getLink().getTitle(), linkTitle, "Link title not as expected"); + assertEquals(feature.getLink().getLength().intValue(), linkLength, "Link length not as expected"); + assertEquals(feature.getLink().getBase(), linkBase, "Link base not as expected"); + assertEquals(feature.getLink().getLang(), linkLang, "Link lang not as expected"); + + assertEquals(feature.getAuthor().getName(), authorName, "Author name not as expected"); + assertEquals(feature.getAuthor().getEmail(), authorEmail, "Author email not as expected"); + assertEquals(feature.getAuthor().getUri(), authorUri, "Author URI not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -213,27 +209,27 @@ public void testUnassignedAbstractFeatureAttributes() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLDocument); - - assertNull("Name not null", feature.getName()); - assertNull("Visibility not null", feature.getVisibility()); - assertNull("Open not null", feature.getOpen()); - assertNull("Address not null", feature.getAddress()); - assertNull("Phone number not null", feature.getPhoneNumber()); - assertNull("Snippet not null", feature.getSnippet()); - assertNull("Description not null", feature.getDescription()); - assertNull("Style URL not null", feature.getStyleUrl()); - assertNull("View not null", feature.getView()); - assertNull("Region not null", feature.getRegion()); - assertNull("Author not null", feature.getAuthor()); - assertNull("Link not null", feature.getLink()); - assertNull("Address details not null", feature.getAddressDetails()); - assertEquals("Style selectors not empty", 0, feature.getStyleSelectors().size()); - assertNull("Time not null", feature.getTimePrimitive()); - assertNull("Extended data not null", feature.getExtendedData()); + assertTrue(feature instanceof KMLDocument, "Root feature is not as expected"); + + assertNull(feature.getName(), "Name not null"); + assertNull(feature.getVisibility(), "Visibility not null"); + assertNull(feature.getOpen(), "Open not null"); + assertNull(feature.getAddress(), "Address not null"); + assertNull(feature.getPhoneNumber(), "Phone number not null"); + assertNull(feature.getSnippet(), "Snippet not null"); + assertNull(feature.getDescription(), "Description not null"); + assertNull(feature.getStyleUrl(), "Style URL not null"); + assertNull(feature.getView(), "View not null"); + assertNull(feature.getRegion(), "Region not null"); + assertNull(feature.getAuthor(), "Author not null"); + assertNull(feature.getLink(), "Link not null"); + assertNull(feature.getAddressDetails(), "Address details not null"); + assertEquals(0, feature.getStyleSelectors().size(), "Style selectors not empty"); + assertNull(feature.getTimePrimitive(), "Time not null"); + assertNull(feature.getExtendedData(), "Extended data not null"); } @SuppressWarnings({"ConstantConditions"}) @@ -259,18 +255,18 @@ public void testPrefixUsage() this.endPrefixedDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Placemark geometry is not as expected"); KMLPoint point = (KMLPoint) geometry; - assertEquals("Altitude mode not as expected", point.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", point.isExtrude(), extrude); - assertEquals("Coordinates not as expected", point.getCoordinates(), coords); + assertEquals(point.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(point.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(point.getCoordinates(), coords, "Coordinates not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -297,18 +293,18 @@ public void testNoDefaultNamespace() sb.append(""); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Placemark geometry is not as expected"); KMLPoint point = (KMLPoint) geometry; - assertEquals("Altitude mode not as expected", point.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", point.isExtrude(), extrude); - assertEquals("Coordinates not as expected", point.getCoordinates(), coords); + assertEquals(point.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(point.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(point.getCoordinates(), coords, "Coordinates not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -334,18 +330,18 @@ public void testPoint() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Placemark geometry is not as expected"); KMLPoint point = (KMLPoint) geometry; - assertEquals("Altitude mode not as expected", point.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", point.isExtrude(), extrude); - assertEquals("Coordinates not as expected", point.getCoordinates(), coords); + assertEquals(point.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(point.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(point.getCoordinates(), coords, "Coordinates not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -380,19 +376,19 @@ public void testLinearRing() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLLinearRing); + assertTrue(geometry instanceof KMLLinearRing, "Placemark geometry is not as expected"); KMLLinearRing ring = (KMLLinearRing) geometry; - assertEquals("Altitude mode not as expected", ring.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", ring.isExtrude(), extrude); - assertEquals("Tessellate not as expected", ring.getTessellate(), tessellate); - assertEquals("Coordinates not as expected", ring.getCoordinates().list, coords); + assertEquals(ring.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(ring.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(ring.getTessellate(), tessellate, "Tessellate not as expected"); + assertEquals(ring.getCoordinates().list, coords, "Coordinates not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -427,19 +423,19 @@ public void testLineString() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLLineString); + assertTrue(geometry instanceof KMLLineString, "Placemark geometry is not as expected"); KMLLineString ring = (KMLLineString) geometry; - assertEquals("Altitude mode not as expected", ring.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", ring.isExtrude(), extrude); - assertEquals("Tessellate not as expected", ring.getTessellate(), tessellate); - assertEquals("Coordinates not as expected", ring.getCoordinates().list, coords); + assertEquals(ring.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(ring.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(ring.getTessellate(), tessellate, "Tessellate not as expected"); + assertEquals(ring.getCoordinates().list, coords, "Coordinates not as expected"); } @SuppressWarnings({"ConstantConditions"}) @@ -512,39 +508,33 @@ public void testPolygon() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLPolygon); + assertTrue(geometry instanceof KMLPolygon, "Placemark geometry is not as expected"); KMLPolygon pgon = (KMLPolygon) geometry; - assertEquals("Altitude mode not as expected", pgon.getAltitudeMode(), altitudeMode); - assertEquals("Extrude not as expected", pgon.isExtrude(), extrude); - assertEquals("Tessellate not as expected", pgon.getTessellate(), tessellate); - - assertEquals("Outer coordinates not as expected", pgon.getOuterBoundary().getCoordinates().list, - outerCoords); - assertEquals("Outer altitude mode not as expected", pgon.getOuterBoundary().getAltitudeMode(), - outerAltitudeMode); - assertEquals("Outer extrude not as expected", pgon.getOuterBoundary().isExtrude(), - outerExtrude); - assertEquals("Outer tessellate not as expected", pgon.getOuterBoundary().getTessellate(), outerTessellate); + assertEquals(pgon.getAltitudeMode(), altitudeMode, "Altitude mode not as expected"); + assertEquals(pgon.isExtrude(), extrude, "Extrude not as expected"); + assertEquals(pgon.getTessellate(), tessellate, "Tessellate not as expected"); + + assertEquals(pgon.getOuterBoundary().getCoordinates().list, outerCoords, "Outer coordinates not as expected"); + assertEquals(pgon.getOuterBoundary().getAltitudeMode(), outerAltitudeMode, "Outer altitude mode not as expected"); + assertEquals(pgon.getOuterBoundary().isExtrude(), outerExtrude, "Outer extrude not as expected"); + assertEquals(pgon.getOuterBoundary().getTessellate(), outerTessellate, "Outer tessellate not as expected"); Iterable innerBoundaries = pgon.getInnerBoundaries(); assertNotNull(innerBoundaries); assertTrue(innerBoundaries.iterator().hasNext()); KMLLinearRing innerBoundary = innerBoundaries.iterator().next(); assertNotNull(innerBoundary); - assertEquals("Inner coordinates not as expected", innerBoundary.getCoordinates().list, - innerCoords); - assertEquals("Inner altitude mode not as expected", innerBoundary.getAltitudeMode(), - innerAltitudeMode); - assertEquals("Inner extrude not as expected", innerBoundary.isExtrude(), - innerExtrude); - assertEquals("Inner tessellate not as expected", innerBoundary.getTessellate(), innerTessellate); + assertEquals(innerBoundary.getCoordinates().list, innerCoords, "Inner coordinates not as expected"); + assertEquals(innerBoundary.getAltitudeMode(), innerAltitudeMode, "Inner altitude mode not as expected"); + assertEquals(innerBoundary.isExtrude(), innerExtrude, "Inner extrude not as expected"); + assertEquals(innerBoundary.getTessellate(), innerTessellate, "Inner tessellate not as expected"); } @Test @@ -560,15 +550,15 @@ public void testSimpleDataType() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLSimpleData dataItem = ((KMLPlacemark) feature).getSimpleData(); - assertNotNull("No SimpleData", dataItem); - assertEquals("SimpleData name not as expected", dataItem.getName(), name); - assertEquals("SimpleData string not as expected", dataItem.getCharacters(), item); + assertNotNull(dataItem, "No SimpleData"); + assertEquals(dataItem.getName(), name, "SimpleData name not as expected"); + assertEquals(dataItem.getCharacters(), item, "SimpleData string not as expected"); } @Test @@ -586,7 +576,7 @@ public void testUnrecognizedElement() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb, true); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); for (Map.Entry field : root.getFields().getEntries()) { @@ -594,18 +584,18 @@ public void testUnrecognizedElement() { UnrecognizedXMLEventParser uField = (UnrecognizedXMLEventParser) field.getValue(); Object o = uField.getField("Placemark"); - assertNotNull("No SimpleData", o); - assertTrue("Unrecognized object not as expected", o instanceof KMLPlacemark); + assertNotNull(o, "No SimpleData"); + assertTrue(o instanceof KMLPlacemark, "Unrecognized object not as expected"); KMLSimpleData dataItem = ((KMLPlacemark) o).getSimpleData(); - assertNotNull("No SimpleData", dataItem); - assertEquals("SimpleData name not as expected", dataItem.getName(), name); - assertEquals("SimpleData string not as expected", dataItem.getCharacters(), item); + assertNotNull(dataItem, "No SimpleData"); + assertEquals(dataItem.getName(), name, "SimpleData name not as expected"); + assertEquals(dataItem.getCharacters(), item, "SimpleData string not as expected"); return; } } - assertTrue("Unrecognized element not found", true); + assertTrue(true, "Unrecognized element not found"); } @SuppressWarnings({"ConstantConditions"}) @@ -639,16 +629,16 @@ public void testCoordinatesParser() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Placemark geometry is not as expected", geometry instanceof KMLLinearRing); + assertTrue(geometry instanceof KMLLinearRing, "Placemark geometry is not as expected"); KMLLinearRing ring = (KMLLinearRing) geometry; - assertEquals("Coordinates not as expected", ring.getCoordinates().list, coords); + assertEquals(ring.getCoordinates().list, coords, "Coordinates not as expected"); } /** Test coordinate tokenizer with a mix of well formed and not so well formed input. */ @@ -677,7 +667,7 @@ public void testCoordinatesTokenizer() positions.add(tokenizer.nextPosition()); } - assertEquals("Coordinates not as expected", coords, positions); + assertEquals(coords, positions, "Coordinates not as expected"); } @Test @@ -697,11 +687,11 @@ public void testNestedUnrecognizedElement() this.endDocument(sb); KMLRoot root = this.newParsedRoot(sb, true); - assertNotNull("KML root is null", root); + assertNotNull(root, "KML root is null"); KMLAbstractFeature doc = root.getFeature(); - assertNotNull("Document is null", doc); - assertTrue("Unrecognized object not as expected", doc instanceof KMLDocument); + assertNotNull(doc, "Document is null"); + assertTrue(doc instanceof KMLDocument, "Unrecognized object not as expected"); for (Map.Entry field : doc.getFields().getEntries()) { @@ -709,18 +699,18 @@ public void testNestedUnrecognizedElement() { UnrecognizedXMLEventParser uField = (UnrecognizedXMLEventParser) field.getValue(); Object o = uField.getField("Placemark"); - assertNotNull("No SimpleData", o); - assertTrue("Unrecognized object not as expected", o instanceof KMLPlacemark); + assertNotNull(o, "No SimpleData"); + assertTrue(o instanceof KMLPlacemark, "Unrecognized object not as expected"); KMLSimpleData dataItem = ((KMLPlacemark) o).getSimpleData(); - assertNotNull("No SimpleData", dataItem); - assertEquals("SimpleData name not as expected", dataItem.getName(), name); - assertEquals("SimpleData string not as expected", dataItem.getCharacters(), item); + assertNotNull(dataItem, "No SimpleData"); + assertEquals(dataItem.getName(), name, "SimpleData name not as expected"); + assertEquals(dataItem.getCharacters(), item, "SimpleData string not as expected"); return; } } - assertTrue("Unrecognized element not found", true); + assertTrue(true, "Unrecognized element not found"); } @Test @@ -729,20 +719,18 @@ public void testGoogleTutorialExample01() KMLRoot root = this.openAndParseFile("testData/KML/GoogleTutorialExample01.kml"); KMLAbstractFeature feature = root.getFeature(); - assertTrue("Root feature is not as expected", feature instanceof KMLPlacemark); - assertEquals("Incorrect name", "Simple placemark", feature.getName()); - assertEquals("Incorrect description", - "Attached to the ground. Intelligently places itself\n" - + " at the height of the underlying terrain.", - feature.getDescription()); + assertTrue(feature instanceof KMLPlacemark, "Root feature is not as expected"); + assertEquals("Simple placemark", feature.getName(), "Incorrect name"); + assertEquals("Attached to the ground. Intelligently places itself\n" + + " at the height of the underlying terrain.", feature.getDescription(), "Incorrect description"); KMLAbstractGeometry geometry = ((KMLPlacemark) feature).getGeometry(); - assertTrue("Geometry not a Point", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Geometry not a Point"); Position coords = ((KMLPoint) geometry).getCoordinates(); - assertEquals("Incorrect latitude", Angle.fromDegrees(37.42228990140251), coords.getLatitude()); - assertEquals("Incorrect longitude", Angle.fromDegrees(-122.0822035425683), coords.getLongitude()); - assertEquals("Incorrect altitude", 0d, coords.getAltitude(), 0.0); + assertEquals(Angle.fromDegrees(37.42228990140251), coords.getLatitude(), "Incorrect latitude"); + assertEquals(Angle.fromDegrees(-122.0822035425683), coords.getLongitude(), "Incorrect longitude"); + assertEquals(0d, coords.getAltitude(), 0.0, "Incorrect altitude"); } @Test @@ -751,14 +739,14 @@ public void testGoogleTutorialExample02() KMLRoot root = this.openAndParseFile("testData/KML/GoogleTutorialExample02.kml"); KMLAbstractFeature document = root.getFeature(); - assertTrue("Root feature is not as expected", document instanceof KMLDocument); + assertTrue(document instanceof KMLDocument, "Root feature is not as expected"); List features = ((KMLDocument) document).getFeatures(); - assertEquals("Incorrect number of features", 1, features.size()); - assertTrue("Root feature is not as expected", features.get(0) instanceof KMLPlacemark); + assertEquals(1, features.size(), "Incorrect number of features"); + assertTrue(features.get(0) instanceof KMLPlacemark, "Root feature is not as expected"); KMLPlacemark placemark = (KMLPlacemark) features.get(0); - assertEquals("Incorrect name", "CDATA example", placemark.getName()); + assertEquals("CDATA example", placemark.getName(), "Incorrect name"); String s = "\n" + "

CDATA Tags are useful!

\n" @@ -766,16 +754,16 @@ public void testGoogleTutorialExample02() + " easier to write when you can avoid using entity\n" + " references.

\n" + " "; - assertFalse("Description string not trimmed", s.equals(placemark.getDescription())); - assertEquals("Incorrect description", s.trim(), placemark.getDescription()); + assertFalse(s.equals(placemark.getDescription()), "Description string not trimmed"); + assertEquals(s.trim(), placemark.getDescription(), "Incorrect description"); KMLAbstractGeometry geometry = placemark.getGeometry(); - assertTrue("Geometry not a Point", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Geometry not a Point"); Position coords = ((KMLPoint) geometry).getCoordinates(); - assertEquals("Incorrect latitude", Angle.fromDegrees(14.996729), coords.getLatitude()); - assertEquals("Incorrect longitude", Angle.fromDegrees(102.595626), coords.getLongitude()); - assertEquals("Incorrect altitude", 0d, coords.getAltitude(), 0.0); + assertEquals(Angle.fromDegrees(14.996729), coords.getLatitude(), "Incorrect latitude"); + assertEquals(Angle.fromDegrees(102.595626), coords.getLongitude(), "Incorrect longitude"); + assertEquals(0d, coords.getAltitude(), 0.0, "Incorrect altitude"); } @Test @@ -784,27 +772,25 @@ public void testGoogleTutorialExample03() KMLRoot root = this.openAndParseFile("testData/KML/GoogleTutorialExample03.kml"); KMLAbstractFeature document = root.getFeature(); - assertTrue("Root feature is not as expected", document instanceof KMLDocument); + assertTrue(document instanceof KMLDocument, "Root feature is not as expected"); List features = ((KMLDocument) document).getFeatures(); - assertEquals("Incorrect number of features", 1, features.size()); - assertTrue("Root feature is not as expected", features.get(0) instanceof KMLPlacemark); + assertEquals(1, features.size(), "Incorrect number of features"); + assertTrue(features.get(0) instanceof KMLPlacemark, "Root feature is not as expected"); KMLPlacemark placemark = (KMLPlacemark) features.get(0); - assertEquals("Incorrect name", "Entity references example", placemark.getName()); - assertEquals("Incorrect description", - "

Entity references are hard to type!

Text\n " + assertEquals("Entity references example", placemark.getName(), "Incorrect name"); + assertEquals("

Entity references are hard to type!

Text\n " + "is more readable and easier to write when you can avoid using\n " - + "entity references.

", - placemark.getDescription()); + + "entity references.

", placemark.getDescription(), "Incorrect description"); KMLAbstractGeometry geometry = placemark.getGeometry(); - assertTrue("Geometry not a Point", geometry instanceof KMLPoint); + assertTrue(geometry instanceof KMLPoint, "Geometry not a Point"); Position coords = ((KMLPoint) geometry).getCoordinates(); - assertEquals("Incorrect latitude", Angle.fromDegrees(14.998518), coords.getLatitude()); - assertEquals("Incorrect longitude", Angle.fromDegrees(102.594411), coords.getLongitude()); - assertEquals("Incorrect altitude", 0d, coords.getAltitude(), 0.0); + assertEquals(Angle.fromDegrees(14.998518), coords.getLatitude(), "Incorrect latitude"); + assertEquals(Angle.fromDegrees(102.594411), coords.getLongitude(), "Incorrect longitude"); + assertEquals(0d, coords.getAltitude(), 0.0, "Incorrect altitude"); } @Test @@ -813,31 +799,29 @@ public void testGoogleTutorialExample04() KMLRoot root = this.openAndParseFile("testData/KML/GoogleTutorialExample04.kml"); KMLAbstractFeature document = root.getFeature(); - assertTrue("Root feature is not as expected", document instanceof KMLFolder); - assertEquals("Incorrect name", "Ground Overlays", document.getName()); - assertEquals("Incorrect description", "Examples of ground overlays", document.getDescription()); + assertTrue(document instanceof KMLFolder, "Root feature is not as expected"); + assertEquals("Ground Overlays", document.getName(), "Incorrect name"); + assertEquals("Examples of ground overlays", document.getDescription(), "Incorrect description"); List features = ((KMLFolder) document).getFeatures(); - assertEquals("Incorrect number of features", 1, features.size()); - assertTrue("Root feature is not as expected", features.get(0) instanceof KMLGroundOverlay); + assertEquals(1, features.size(), "Incorrect number of features"); + assertTrue(features.get(0) instanceof KMLGroundOverlay, "Root feature is not as expected"); KMLGroundOverlay overlay = (KMLGroundOverlay) features.get(0); - assertEquals("Incorrect name", "Large-scale overlay on terrain", overlay.getName()); - assertEquals("Incorrect description", - "Overlay shows Mount Etna erupting\n" - + " on July 13th, 2001.", overlay.getDescription()); + assertEquals("Large-scale overlay on terrain", overlay.getName(), "Incorrect name"); + assertEquals("Overlay shows Mount Etna erupting\n" + + " on July 13th, 2001.", overlay.getDescription(), "Incorrect description"); KMLIcon icon = overlay.getIcon(); - assertNotNull("Overlay icon is null", icon); - assertEquals("Incorrect icon href", "https://developers.google.com/kml/documentation/images/etna.jpg", - icon.getHref()); + assertNotNull(icon, "Overlay icon is null"); + assertEquals("https://developers.google.com/kml/documentation/images/etna.jpg", icon.getHref(), "Incorrect icon href"); KMLLatLonBox box = overlay.getLatLonBox(); - assertNotNull("Overlay LatLonBox is null", box); - assertEquals("Incorrect box north", 37.91904192681665, box.getNorth(), 0.0); - assertEquals("Incorrect box south", 37.46543388598137, box.getSouth(), 0.0); - assertEquals("Incorrect box east", 15.35832653742206, box.getEast(), 0.0); - assertEquals("Incorrect box west", 14.60128369746704, box.getWest(), 0.0); + assertNotNull(box, "Overlay LatLonBox is null"); + assertEquals(37.91904192681665, box.getNorth(), 0.0, "Incorrect box north"); + assertEquals(37.46543388598137, box.getSouth(), 0.0, "Incorrect box south"); + assertEquals(15.35832653742206, box.getEast(), 0.0, "Incorrect box east"); + assertEquals(14.60128369746704, box.getWest(), 0.0, "Incorrect box west"); } @Test @@ -846,33 +830,33 @@ public void testStyleReference() KMLRoot root = this.openAndParseFile("testData/KML/StyleReferences.kml"); KMLAbstractFeature document = root.getFeature(); - assertTrue("Root feature is not as expected", document instanceof KMLDocument); + assertTrue(document instanceof KMLDocument, "Root feature is not as expected"); List features = ((KMLDocument) document).getFeatures(); - assertEquals("Incorrect number of features", 1, features.size()); - assertTrue("Document feature is not as expected", features.get(0) instanceof KMLPlacemark); + assertEquals(1, features.size(), "Incorrect number of features"); + assertTrue(features.get(0) instanceof KMLPlacemark, "Document feature is not as expected"); List styles = document.getStyleSelectors(); - assertEquals("Incorrect number of styles", 1, styles.size()); + assertEquals(1, styles.size(), "Incorrect number of styles"); // // TODO: re-enable w/o relying on getStyleUrlResolved // KMLPlacemark placemark = (KMLPlacemark) features.get(0); -// assertEquals("Incorrect name", "Building 41", placemark.getName()); -// assertEquals("Incorrect styleUrl", "#transBluePoly", placemark.getStyleUrl().getCharacters()); -// assertNotNull("Style is null", placemark.getStyleUrlResolved()); +// assertEquals("Building 41", placemark.getName(), "Incorrect name"); +// assertEquals("#transBluePoly", placemark.getStyleUrl().getCharacters(), "Incorrect styleUrl"); +// assertNotNull(placemark.getStyleUrlResolved(), "Style is null"); // -// assertTrue("Placemark feature is not as expected", placemark.getGeometry() instanceof KMLPolygon); +// assertTrue(placemark.getGeometry() instanceof KMLPolygon, "Placemark feature is not as expected"); // KMLPolygon pgon = (KMLPolygon) placemark.getGeometry(); -// assertEquals("Incorrect extrude value", (Boolean) true, pgon.getExtrude()); -// assertEquals("Incorrect altitude mode", "relativeToGround", pgon.getAltitudeMode()); +// assertEquals((Boolean) true, pgon.getExtrude(), "Incorrect extrude value"); +// assertEquals("relativeToGround", pgon.getAltitudeMode(), "Incorrect altitude mode"); // // KMLStyle style = placemark.getStyleUrlResolved(); // KMLLineStyle lineStyle = style.getLineStyle(); -// assertNotNull("LineStyle is null", lineStyle); -// assertEquals("Line style width is not as expected", 1.5, lineStyle.getWidth()); +// assertNotNull(lineStyle, "LineStyle is null"); +// assertEquals(1.5, lineStyle.getWidth(), "Line style width is not as expected"); // // KMLPolyStyle polyStyle = style.getPolyStyle(); -// assertNotNull("PolyStyle is null", polyStyle); -// assertEquals("Poly style color is not as expected", "7dff0000", polyStyle.getColor()); +// assertNotNull(polyStyle, "PolyStyle is null"); +// assertEquals("7dff0000", polyStyle.getColor(), "Poly style color is not as expected"); } @Test @@ -902,7 +886,7 @@ public void testKMZFromFileURL() for (String name : fileNames) { InputStream is = root.getKMLDoc().getSupportFileStream(name); - assertNotNull("Support file not found in KMZ: " + name, is); + assertNotNull(is, "Support file not found in KMZ: " + name); } } catch (Exception e) @@ -1010,9 +994,9 @@ public void notify(XMLParserNotification notificationEvent) }); root.parse(); - assertNotNull("KML root is null", root); - assertTrue("Parser notification occurred\n" + sourceDoc + ":" + parserMessage, - parserMessage.length() == 0); + assertNotNull(root, "KML root is null"); + assertTrue(parserMessage.length() == 0, + "Parser notification occurred\n" + sourceDoc + ":" + parserMessage); } catch (Exception e) { diff --git a/test/gov/nasa/worldwind/ogc/wcs/WCSCapabilitiesParsingTest.java b/test/gov/nasa/worldwind/ogc/wcs/WCSCapabilitiesParsingTest.java index 4fea9b0267..0c8f29a59c 100644 --- a/test/gov/nasa/worldwind/ogc/wcs/WCSCapabilitiesParsingTest.java +++ b/test/gov/nasa/worldwind/ogc/wcs/WCSCapabilitiesParsingTest.java @@ -30,16 +30,12 @@ import gov.nasa.worldwind.ogc.ows.*; import gov.nasa.worldwind.ogc.wcs.wcs100.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class WCSCapabilitiesParsingTest { @Test @@ -56,132 +52,129 @@ public void testParsing001() e.printStackTrace(); } - assertNotNull("Version is null", caps.getVersion()); - assertEquals("Incorrect version number", "1.0.0", caps.getVersion()); - assertEquals("Incorrect update sequence", "2013-06-28T16:26:00Z", caps.getUpdateSequence()); + assertNotNull(caps.getVersion(), "Version is null"); + assertEquals("1.0.0", caps.getVersion(), "Incorrect version number"); + assertEquals("2013-06-28T16:26:00Z", caps.getUpdateSequence(), "Incorrect update sequence"); WCS100Service service = caps.getService(); - assertNotNull("Service is null", service); + assertNotNull(service, "Service is null"); WCS100MetadataLink metadataLink = service.getMetadataLink(); - assertNotNull("MetadataLink is null", metadataLink); - assertEquals("Incorrect metadataLink href", "http://worldwind26.arc.nasa.gov", metadataLink.getHref()); - assertEquals("Incorrect type value", "simple", metadataLink.getType()); - assertEquals("Incorrect metadataType value", "TC211", metadataLink.getMetadataType()); + assertNotNull(metadataLink, "MetadataLink is null"); + assertEquals("http://worldwind26.arc.nasa.gov", metadataLink.getHref(), "Incorrect metadataLink href"); + assertEquals("simple", metadataLink.getType(), "Incorrect type value"); + assertEquals("TC211", metadataLink.getMetadataType(), "Incorrect metadataType value"); String description = service.getDescription(); - assertNotNull("Service description is null", description); - assertTrue("Incorrect description", description.startsWith("WorldWind MapServer Elevation test")); + assertNotNull(description, "Service description is null"); + assertTrue(description.startsWith("WorldWind MapServer Elevation test"), "Incorrect description"); - assertNotNull("Service name is null", service.getName()); - assertEquals("Incorrect service name", "MapServer WCS", service.getName()); + assertNotNull(service.getName(), "Service name is null"); + assertEquals("MapServer WCS", service.getName(), "Incorrect service name"); - assertNotNull("Service label is null", service.getLabel()); - assertEquals("Incorrect service label", "WorldWind MapServer Elevation", service.getLabel()); + assertNotNull(service.getLabel(), "Service label is null"); + assertEquals("WorldWind MapServer Elevation", service.getLabel(), "Incorrect service label"); List keywords = service.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect keyword count", 5, keywords.size()); - assertTrue("Missing keyword", keywords.contains("wcs")); - assertTrue("Missing keyword", keywords.contains("test")); - assertTrue("Missing keyword", keywords.contains("FAA")); - assertTrue("Missing keyword", keywords.contains("charts")); - assertTrue("Missing keyword", keywords.contains("aeronautical")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(5, keywords.size(), "Incorrect keyword count"); + assertTrue(keywords.contains("wcs"), "Missing keyword"); + assertTrue(keywords.contains("test"), "Missing keyword"); + assertTrue(keywords.contains("FAA"), "Missing keyword"); + assertTrue(keywords.contains("charts"), "Missing keyword"); + assertTrue(keywords.contains("aeronautical"), "Missing keyword"); WCS100ResponsibleParty responsibleParty = service.getResponsibleParty(); - assertNotNull("ResponsibleParty is null", responsibleParty); - assertNotNull("IndividualName is null", responsibleParty.getIndividualName()); - assertEquals("Incorrect individualName", "Randolph Kim", responsibleParty.getIndividualName()); - assertNotNull("OrganisationName is null", responsibleParty.getOrganisationName()); - assertEquals("Incorrect organisationName", "NASA", responsibleParty.getOrganisationName()); - assertNotNull("PostionName is null", responsibleParty.getPositionName()); - assertEquals("Incorrect positionName", "manager", responsibleParty.getPositionName()); + assertNotNull(responsibleParty, "ResponsibleParty is null"); + assertNotNull(responsibleParty.getIndividualName(), "IndividualName is null"); + assertEquals("Randolph Kim", responsibleParty.getIndividualName(), "Incorrect individualName"); + assertNotNull(responsibleParty.getOrganisationName(), "OrganisationName is null"); + assertEquals("NASA", responsibleParty.getOrganisationName(), "Incorrect organisationName"); + assertNotNull(responsibleParty.getPositionName(), "PostionName is null"); + assertEquals("manager", responsibleParty.getPositionName(), "Incorrect positionName"); OWSContactInfo contactInfo = responsibleParty.getContactInfo(); - assertNotNull("ContactInfo is null", contactInfo); + assertNotNull(contactInfo, "ContactInfo is null"); OWSAddress address = contactInfo.getAddress(); - assertNotNull("Address is null", address); - assertNotNull("City is null", address.getCity()); - assertEquals("Incorrect city", "Moffett Field", address.getCity()); - assertNotNull("Country is null", address.getCountries().get(0)); - assertEquals("Incorrect country", "USA", address.getCountries().get(0)); - assertNotNull("ElectronicMailAddress is null", address.getElectronicMailAddresses().get(0)); - assertEquals("Incorrect electronicMailAddress", "none@nasa.gov", address.getElectronicMailAddresses().get(0)); - assertNotNull("DeliveryPoint is null", address.getDeliveryPoints().get(0)); - assertEquals("Incorrect deliveryPoint", "NASA Ames Research Center", address.getDeliveryPoints().get(0)); - assertNotNull("AdministrativeArea is null", address.getAdministrativeArea()); - assertEquals("Incorrect deliveryPoint", "CA", address.getAdministrativeArea()); + assertNotNull(address, "Address is null"); + assertNotNull(address.getCity(), "City is null"); + assertEquals("Moffett Field", address.getCity(), "Incorrect city"); + assertNotNull(address.getCountries().get(0), "Country is null"); + assertEquals("USA", address.getCountries().get(0), "Incorrect country"); + assertNotNull(address.getElectronicMailAddresses().get(0), "ElectronicMailAddress is null"); + assertEquals("none@nasa.gov", address.getElectronicMailAddresses().get(0), "Incorrect electronicMailAddress"); + assertNotNull(address.getDeliveryPoints().get(0), "DeliveryPoint is null"); + assertEquals("NASA Ames Research Center", address.getDeliveryPoints().get(0), "Incorrect deliveryPoint"); + assertNotNull(address.getAdministrativeArea(), "AdministrativeArea is null"); + assertEquals("CA", address.getAdministrativeArea(), "Incorrect deliveryPoint"); OWSPhone phone = contactInfo.getPhone(); - assertNotNull("Phone is null", phone); - assertNotNull("Voice is null", phone.getVoices().get(0)); - assertEquals("Incorrect voice", "000-000-0000", phone.getVoices().get(0)); - assertNotNull("Facsimile is null", phone.getFacsimiles().get(0)); - assertEquals("Incorrect facsimile", "000-000-0000", phone.getFacsimiles().get(0)); - assertEquals("Incorrect contactInfo onlineResource href", "http://worldwind26.arc.nasa.gov/wms2?", - contactInfo.getOnlineResource()); + assertNotNull(phone, "Phone is null"); + assertNotNull(phone.getVoices().get(0), "Voice is null"); + assertEquals("000-000-0000", phone.getVoices().get(0), "Incorrect voice"); + assertNotNull(phone.getFacsimiles().get(0), "Facsimile is null"); + assertEquals("000-000-0000", phone.getFacsimiles().get(0), "Incorrect facsimile"); + assertEquals("http://worldwind26.arc.nasa.gov/wms2?", contactInfo.getOnlineResource(), "Incorrect contactInfo onlineResource href"); - assertNotNull("Fees is null", service.getFees()); - assertEquals("Incorrect country", "none", service.getFees()); + assertNotNull(service.getFees(), "Fees is null"); + assertEquals("none", service.getFees(), "Incorrect country"); List accessConstraints = service.getAccessConstraints(); - assertNotNull("AccessConstraints is null", accessConstraints); - assertEquals("Incorrect number of access constraints", 1, accessConstraints.size()); - assertEquals("Incorrect accessConstraint", "none", accessConstraints.iterator().next()); + assertNotNull(accessConstraints, "AccessConstraints is null"); + assertEquals(1, accessConstraints.size(), "Incorrect number of access constraints"); + assertEquals("none", accessConstraints.iterator().next(), "Incorrect accessConstraint"); WCS100Capability capability = caps.getCapability(); - assertNotNull("Capability is null", capability); + assertNotNull(capability, "Capability is null"); WCS100Request request = capability.getRequest(); - assertNotNull("Request is null", request); - assertNotNull("Request descriptions is null", request.getRequests()); - assertEquals("Incorrect request description count", 3, request.getRequests().size()); - assertNotNull("GetCapabilities request description is null", request.getRequest("GetCapabilities")); - assertNotNull("DescribeCoverage request description is null", request.getRequest("DescribeCoverage")); - assertNotNull("GetCoverage request description is null", request.getRequest("GetCoverage")); + assertNotNull(request, "Request is null"); + assertNotNull(request.getRequests(), "Request descriptions is null"); + assertEquals(3, request.getRequests().size(), "Incorrect request description count"); + assertNotNull(request.getRequest("GetCapabilities"), "GetCapabilities request description is null"); + assertNotNull(request.getRequest("DescribeCoverage"), "DescribeCoverage request description is null"); + assertNotNull(request.getRequest("GetCoverage"), "GetCoverage request description is null"); checkRequestDescription(request.getRequest("GetCapabilities"), "http://worldwind26.arc.nasa.gov/wms2?"); checkRequestDescription(request.getRequest("DescribeCoverage"), "http://worldwind26.arc.nasa.gov/wms2?"); checkRequestDescription(request.getRequest("GetCoverage"), "http://worldwind26.arc.nasa.gov/wms2?"); WCS100Exception exception = capability.getException(); - assertNotNull("Exception is null", exception); - assertNotNull("Exception Formats is null", exception.getFormats()); - assertEquals("Incorrect exception format count", 1, exception.getFormats().size()); + assertNotNull(exception, "Exception is null"); + assertNotNull(exception.getFormats(), "Exception Formats is null"); + assertEquals(1, exception.getFormats().size(), "Incorrect exception format count"); Iterator iterator = exception.getFormats().iterator(); - assertEquals("Incorrect exception format", "application/vnd.ogc.se_xml", iterator.next()); + assertEquals("application/vnd.ogc.se_xml", iterator.next(), "Incorrect exception format"); - assertNotNull("ContentMetadata is null", caps.getContentMetadata()); + assertNotNull(caps.getContentMetadata(), "ContentMetadata is null"); List coverages = caps.getContentMetadata().getCoverageOfferings(); - assertNotNull("CoverageOfferingBriefs is null", coverages); - assertEquals("Incorrect CoverageOfferingBrief description count", 6, coverages.size()); + assertNotNull(coverages, "CoverageOfferingBriefs is null"); + assertEquals(6, coverages.size(), "Incorrect CoverageOfferingBrief description count"); WCS100CoverageOfferingBrief coverage = coverages.get(0); - assertNotNull("CoverageOfferingBrief 0 is null", coverage); - assertNotNull("CoverageOfferingBrief 0 name is null", coverage.getName()); - assertEquals("Incorrect CoverageOfferingBrief 0 name", "aster_v2", coverage.getName()); - assertNotNull("CoverageOfferingBrief 0 label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOfferingBrief 0 label", "ASTER version 2", coverage.getLabel()); + assertNotNull(coverage, "CoverageOfferingBrief 0 is null"); + assertNotNull(coverage.getName(), "CoverageOfferingBrief 0 name is null"); + assertEquals("aster_v2", coverage.getName(), "Incorrect CoverageOfferingBrief 0 name"); + assertNotNull(coverage.getLabel(), "CoverageOfferingBrief 0 label is null"); + assertEquals("ASTER version 2", coverage.getLabel(), "Incorrect CoverageOfferingBrief 0 label"); WCS100LonLatEnvelope envelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope 0 is null", envelope); - assertNotNull("LonLatEnvelope 0 positions is null", envelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope 0 SRS", "urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope 0 position count", 2, envelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope 0 position 0", "-180 -83", - envelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope 0 position 1", "180 83", envelope.getPositions().get(1).getPosString()); + assertNotNull(envelope, "LonLatEnvelope 0 is null"); + assertNotNull(envelope.getPositions(), "LonLatEnvelope 0 positions is null"); + assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName(), "Incorrect LonLatEnvelope 0 SRS"); + assertEquals(2, envelope.getPositions().size(), "Incorrect LonLatEnvelope 0 position count"); + assertEquals("-180 -83", envelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope 0 position 0"); + assertEquals("180 83", envelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope 0 position 1"); coverage = coverages.get(1); - assertNotNull("CoverageOfferingBrief 1 is null", coverage); - assertNotNull("CoverageOfferingBrief 1 name is null", coverage.getName()); - assertEquals("Incorrect CoverageOfferingBrief 1 name", "USGS-NED", coverage.getName()); - assertNotNull("CoverageOfferingBrief 1 label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOfferingBrief 1 label", "USGS NED", coverage.getLabel()); + assertNotNull(coverage, "CoverageOfferingBrief 1 is null"); + assertNotNull(coverage.getName(), "CoverageOfferingBrief 1 name is null"); + assertEquals("USGS-NED", coverage.getName(), "Incorrect CoverageOfferingBrief 1 name"); + assertNotNull(coverage.getLabel(), "CoverageOfferingBrief 1 label is null"); + assertEquals("USGS NED", coverage.getLabel(), "Incorrect CoverageOfferingBrief 1 label"); envelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope 1 is null", envelope); - assertNotNull("LonLatEnvelope 1 positions is null", envelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope 1 SRS", "urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope 1 position count", 2, envelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope 1 position 0", "-125 25", envelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope 1 position 1", "-65.5 50", - envelope.getPositions().get(1).getPosString()); + assertNotNull(envelope, "LonLatEnvelope 1 is null"); + assertNotNull(envelope.getPositions(), "LonLatEnvelope 1 positions is null"); + assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName(), "Incorrect LonLatEnvelope 1 SRS"); + assertEquals(2, envelope.getPositions().size(), "Incorrect LonLatEnvelope 1 position count"); + assertEquals("-125 25", envelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope 1 position 0"); + assertEquals("-65.5 50", envelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope 1 position 1"); // There are more CoverageOfferingBrief elements in the file, but testing the two above is adequate. } @@ -200,146 +193,132 @@ public void testParsing002() e.printStackTrace(); } - assertNotNull("Version is null", caps.getVersion()); - assertEquals("Incorrect version number", "1.0.0", caps.getVersion()); - assertEquals("Incorrect update sequence", "105", caps.getUpdateSequence()); + assertNotNull(caps.getVersion(), "Version is null"); + assertEquals("1.0.0", caps.getVersion(), "Incorrect version number"); + assertEquals("105", caps.getUpdateSequence(), "Incorrect update sequence"); WCS100Service service = caps.getService(); - assertNotNull("Service is null", service); + assertNotNull(service, "Service is null"); WCS100MetadataLink metadataLink = service.getMetadataLink(); - assertNotNull("MetadataLink is null", metadataLink); - assertEquals("Incorrect metadataLink about value", "http://geoserver.sourceforge.net/html/index.php", - metadataLink.getField("about")); - assertEquals("Incorrect metadataLink type value", "simple", metadataLink.getField("type")); - assertEquals("Incorrect metadataLink metadataType value", "other", metadataLink.getField("metadataType")); + assertNotNull(metadataLink, "MetadataLink is null"); + assertEquals("http://geoserver.sourceforge.net/html/index.php", metadataLink.getField("about"), "Incorrect metadataLink about value"); + assertEquals("simple", metadataLink.getField("type"), "Incorrect metadataLink type value"); + assertEquals("other", metadataLink.getField("metadataType"), "Incorrect metadataLink metadataType value"); String description = service.getDescription(); - assertNotNull("Service description is null", description); - assertTrue("Incorrect description", - description.startsWith("This server implements the WCS specification 1.0")); + assertNotNull(description, "Service description is null"); + assertTrue(description.startsWith("This server implements the WCS specification 1.0"), "Incorrect description"); - assertNotNull("Service name is null", service.getName()); - assertEquals("Incorrect service name", "WCS", service.getName()); + assertNotNull(service.getName(), "Service name is null"); + assertEquals("WCS", service.getName(), "Incorrect service name"); - assertNotNull("Service label is null", service.getLabel()); - assertEquals("Incorrect service label", "Web Coverage Service", service.getLabel()); + assertNotNull(service.getLabel(), "Service label is null"); + assertEquals("Web Coverage Service", service.getLabel(), "Incorrect service label"); List keywords = service.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect keyword count", 3, keywords.size()); - assertTrue("Missing keyword", keywords.contains("WCS")); - assertTrue("Missing keyword", keywords.contains("WMS")); - assertTrue("Missing keyword", keywords.contains("GEOSERVER")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect keyword count"); + assertTrue(keywords.contains("WCS"), "Missing keyword"); + assertTrue(keywords.contains("WMS"), "Missing keyword"); + assertTrue(keywords.contains("GEOSERVER"), "Missing keyword"); WCS100ResponsibleParty responsibleParty = service.getResponsibleParty(); - assertNotNull("ResponsibleParty is null", responsibleParty); - assertNotNull("IndividualName is null", responsibleParty.getIndividualName()); - assertEquals("Incorrect individualName", "Claudius Ptolomaeus", responsibleParty.getIndividualName()); - assertNotNull("OrganisationName is null", responsibleParty.getOrganisationName()); - assertEquals("Incorrect organisationName", "The ancient geographes INC", - responsibleParty.getOrganisationName()); - assertNotNull("PostionName is null", responsibleParty.getPositionName()); - assertEquals("Incorrect positionName", "Chief geographer", responsibleParty.getPositionName()); + assertNotNull(responsibleParty, "ResponsibleParty is null"); + assertNotNull(responsibleParty.getIndividualName(), "IndividualName is null"); + assertEquals("Claudius Ptolomaeus", responsibleParty.getIndividualName(), "Incorrect individualName"); + assertNotNull(responsibleParty.getOrganisationName(), "OrganisationName is null"); + assertEquals("The ancient geographes INC", responsibleParty.getOrganisationName(), "Incorrect organisationName"); + assertNotNull(responsibleParty.getPositionName(), "PostionName is null"); + assertEquals("Chief geographer", responsibleParty.getPositionName(), "Incorrect positionName"); OWSContactInfo contactInfo = responsibleParty.getContactInfo(); - assertNotNull("ContactInfo is null", contactInfo); + assertNotNull(contactInfo, "ContactInfo is null"); OWSAddress address = contactInfo.getAddress(); - assertNotNull("Address is null", address); - assertNotNull("City is null", address.getCity()); - assertEquals("Incorrect city", "Alexandria", address.getCity()); - assertNotNull("Country is null", address.getCountries()); - assertEquals("Incorrect country", "Egypt", address.getCountries().get(0)); - assertNotNull("ElectronicMailAddress is null", address.getElectronicMailAddresses()); - assertEquals("Incorrect electronicMailAddress", "claudius.ptolomaeus@gmail.com", - address.getElectronicMailAddresses().get(0)); - - assertNotNull("Fees is null", service.getFees()); - assertEquals("Incorrect country", "NONE", service.getFees()); + assertNotNull(address, "Address is null"); + assertNotNull(address.getCity(), "City is null"); + assertEquals("Alexandria", address.getCity(), "Incorrect city"); + assertNotNull(address.getCountries(), "Country is null"); + assertEquals("Egypt", address.getCountries().get(0), "Incorrect country"); + assertNotNull(address.getElectronicMailAddresses(), "ElectronicMailAddress is null"); + assertEquals("claudius.ptolomaeus@gmail.com", address.getElectronicMailAddresses().get(0), "Incorrect electronicMailAddress"); + + assertNotNull(service.getFees(), "Fees is null"); + assertEquals("NONE", service.getFees(), "Incorrect country"); List accessConstraints = service.getAccessConstraints(); - assertNotNull("AccessConstraints is null", accessConstraints); - assertEquals("Incorrect number of access constraints", 1, accessConstraints.size()); - assertEquals("Incorrect accessConstraint", "NONE", accessConstraints.iterator().next()); + assertNotNull(accessConstraints, "AccessConstraints is null"); + assertEquals(1, accessConstraints.size(), "Incorrect number of access constraints"); + assertEquals("NONE", accessConstraints.iterator().next(), "Incorrect accessConstraint"); WCS100Capability capability = caps.getCapability(); - assertNotNull("Capability is null", capability); + assertNotNull(capability, "Capability is null"); WCS100Request request = capability.getRequest(); - assertNotNull("Request is null", request); - assertNotNull("Request descriptions is null", request.getRequests()); - assertEquals("Incorrect request description count", 3, request.getRequests().size()); - assertNotNull("GetCapabilities request description is null", request.getRequest("GetCapabilities")); - assertNotNull("DescribeCoverage request description is null", request.getRequest("DescribeCoverage")); - assertNotNull("GetCoverage request description is null", request.getRequest("GetCoverage")); + assertNotNull(request, "Request is null"); + assertNotNull(request.getRequests(), "Request descriptions is null"); + assertEquals(3, request.getRequests().size(), "Incorrect request description count"); + assertNotNull(request.getRequest("GetCapabilities"), "GetCapabilities request description is null"); + assertNotNull(request.getRequest("DescribeCoverage"), "DescribeCoverage request description is null"); + assertNotNull(request.getRequest("GetCoverage"), "GetCoverage request description is null"); checkRequestDescription(request.getRequest("GetCapabilities"), "http://10.0.1.198:8080/geoserver/wcs?"); checkRequestDescription(request.getRequest("DescribeCoverage"), "http://10.0.1.198:8080/geoserver/wcs?"); checkRequestDescription(request.getRequest("GetCoverage"), "http://10.0.1.198:8080/geoserver/wcs?"); WCS100Exception exception = capability.getException(); - assertNotNull("Exception is null", exception); - assertNotNull("Exception Formats is null", exception.getFormats()); - assertEquals("Incorrect exception format count", 1, exception.getFormats().size()); + assertNotNull(exception, "Exception is null"); + assertNotNull(exception.getFormats(), "Exception Formats is null"); + assertEquals(1, exception.getFormats().size(), "Incorrect exception format count"); Iterator iterator = exception.getFormats().iterator(); - assertEquals("Incorrect exception format", "application/vnd.ogc.se_xml", iterator.next()); + assertEquals("application/vnd.ogc.se_xml", iterator.next(), "Incorrect exception format"); - assertNotNull("ContentMetadata is null", caps.getContentMetadata()); + assertNotNull(caps.getContentMetadata(), "ContentMetadata is null"); List coverages = caps.getContentMetadata().getCoverageOfferings(); - assertNotNull("CoverageOfferingBriefs is null", coverages); - assertEquals("Incorrect CoverageOfferingBrief description count", 7, coverages.size()); + assertNotNull(coverages, "CoverageOfferingBriefs is null"); + assertEquals(7, coverages.size(), "Incorrect CoverageOfferingBrief description count"); WCS100CoverageOfferingBrief coverage = coverages.get(0); - assertNotNull("CoverageOfferingBrief 0 is null", coverage); - assertNotNull("CoverageOfferingBrief 0 description is null", coverage.getDescription()); - assertEquals("Incorrect CoverageOfferingBrief 0 description", "Generated from arcGridSample", - coverage.getDescription()); - assertNotNull("CoverageOfferingBrief 0 name is null", coverage.getName()); - assertEquals("Incorrect CoverageOfferingBrief 0 name", "nurc:Arc_Sample", - coverage.getName()); - assertNotNull("CoverageOfferingBrief 0 label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOfferingBrief 0 label", "A sample ArcGrid file", - coverage.getLabel()); + assertNotNull(coverage, "CoverageOfferingBrief 0 is null"); + assertNotNull(coverage.getDescription(), "CoverageOfferingBrief 0 description is null"); + assertEquals("Generated from arcGridSample", coverage.getDescription(), "Incorrect CoverageOfferingBrief 0 description"); + assertNotNull(coverage.getName(), "CoverageOfferingBrief 0 name is null"); + assertEquals("nurc:Arc_Sample", coverage.getName(), "Incorrect CoverageOfferingBrief 0 name"); + assertNotNull(coverage.getLabel(), "CoverageOfferingBrief 0 label is null"); + assertEquals("A sample ArcGrid file", coverage.getLabel(), "Incorrect CoverageOfferingBrief 0 label"); WCS100LonLatEnvelope envelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope 0 is null", envelope); - assertNotNull("LonLatEnvelope 0 positions is null", envelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope 0 SRS", "urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope 0 position count", 2, envelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope 0 position 0", "-180.0 -90.0", - envelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope 0 position 1", "180.0 90.0", - envelope.getPositions().get(1).getPosString()); + assertNotNull(envelope, "LonLatEnvelope 0 is null"); + assertNotNull(envelope.getPositions(), "LonLatEnvelope 0 positions is null"); + assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName(), "Incorrect LonLatEnvelope 0 SRS"); + assertEquals(2, envelope.getPositions().size(), "Incorrect LonLatEnvelope 0 position count"); + assertEquals("-180.0 -90.0", envelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope 0 position 0"); + assertEquals("180.0 90.0", envelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope 0 position 1"); keywords = coverage.getKeywords(); - assertTrue("Keywords is null for CoverageOfferingBrief 0", keywords != null); - assertEquals("Incorrect keyword count for CoverageOfferingBrief 0", 3, keywords.size()); - assertTrue("Missing keyword for CoverageOfferingBrief 0", keywords.contains("WCS")); - assertTrue("Missing keyword for CoverageOfferingBrief 0", keywords.contains("arcGridSample")); - assertTrue("Missing keyword for CoverageOfferingBrief 0", keywords.contains("arcGridSample_Coverage")); + assertTrue(keywords != null, "Keywords is null for CoverageOfferingBrief 0"); + assertEquals(3, keywords.size(), "Incorrect keyword count for CoverageOfferingBrief 0"); + assertTrue(keywords.contains("WCS"), "Missing keyword for CoverageOfferingBrief 0"); + assertTrue(keywords.contains("arcGridSample"), "Missing keyword for CoverageOfferingBrief 0"); + assertTrue(keywords.contains("arcGridSample_Coverage"), "Missing keyword for CoverageOfferingBrief 0"); coverage = coverages.get(1); - assertNotNull("CoverageOfferingBrief 1 is null", coverage); - assertNotNull("CoverageOfferingBrief 1 description is null", coverage.getDescription()); - assertEquals("Incorrect CoverageOfferingBrief 1 description", "Generated from ImageMosaic", - coverage.getDescription()); - assertNotNull("CoverageOfferingBrief 1 name is null", coverage.getName()); - assertEquals("Incorrect CoverageOfferingBrief 1 name", "WW:aster_v2", - coverage.getName()); - assertNotNull("CoverageOfferingBrief 1 label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOfferingBrief 1 label", "ASTER", - coverage.getLabel()); + assertNotNull(coverage, "CoverageOfferingBrief 1 is null"); + assertNotNull(coverage.getDescription(), "CoverageOfferingBrief 1 description is null"); + assertEquals("Generated from ImageMosaic", coverage.getDescription(), "Incorrect CoverageOfferingBrief 1 description"); + assertNotNull(coverage.getName(), "CoverageOfferingBrief 1 name is null"); + assertEquals("WW:aster_v2", coverage.getName(), "Incorrect CoverageOfferingBrief 1 name"); + assertNotNull(coverage.getLabel(), "CoverageOfferingBrief 1 label is null"); + assertEquals("ASTER", coverage.getLabel(), "Incorrect CoverageOfferingBrief 1 label"); envelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope 1 is null", envelope); - assertNotNull("LonLatEnvelope 1 positions is null", envelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope 1 SRS", "urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope 1 position count", 2, envelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope 1 position 0", "-180.0001388888889 -83.0001388888889", - envelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope 1 position 1", "180.00013888888887 83.00013888888888", - envelope.getPositions().get(1).getPosString()); + assertNotNull(envelope, "LonLatEnvelope 1 is null"); + assertNotNull(envelope.getPositions(), "LonLatEnvelope 1 positions is null"); + assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", envelope.getSRSName(), "Incorrect LonLatEnvelope 1 SRS"); + assertEquals(2, envelope.getPositions().size(), "Incorrect LonLatEnvelope 1 position count"); + assertEquals("-180.0001388888889 -83.0001388888889", envelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope 1 position 0"); + assertEquals("180.00013888888887 83.00013888888888", envelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope 1 position 1"); keywords = coverage.getKeywords(); - assertTrue("Keywords is null for CoverageOfferingBrief 1", keywords != null); - assertEquals("Incorrect keyword count for CoverageOfferingBrief 1", 3, keywords.size()); - assertTrue("Missing keyword for CoverageOfferingBrief 1", keywords.contains("WCS")); - assertTrue("Missing keyword for CoverageOfferingBrief 1", keywords.contains("ImageMosaic")); - assertTrue("Missing keyword for CoverageOfferingBrief 1", keywords.contains("ASTER")); + assertTrue(keywords != null, "Keywords is null for CoverageOfferingBrief 1"); + assertEquals(3, keywords.size(), "Incorrect keyword count for CoverageOfferingBrief 1"); + assertTrue(keywords.contains("WCS"), "Missing keyword for CoverageOfferingBrief 1"); + assertTrue(keywords.contains("ImageMosaic"), "Missing keyword for CoverageOfferingBrief 1"); + assertTrue(keywords.contains("ASTER"), "Missing keyword for CoverageOfferingBrief 1"); // There are more CoverageOfferingBrief elements in the file, but testing the two above is adequate. } @@ -358,338 +337,322 @@ public void testParsing003() e.printStackTrace(); } - assertNotNull("Version is null", caps.getVersion()); - assertEquals("Incorrect version number", "1.1.1", caps.getVersion()); - assertEquals("Incorrect update sequence", "99", caps.getUpdateSequence()); + assertNotNull(caps.getVersion(), "Version is null"); + assertEquals("1.1.1", caps.getVersion(), "Incorrect version number"); + assertEquals("99", caps.getUpdateSequence(), "Incorrect update sequence"); OWSServiceIdentification serviceIdentification = caps.getServiceIdentification(); - assertNotNull("Service Identification is null", serviceIdentification); - assertEquals("Incorrect Fees", "NONE", serviceIdentification.getFees()); - assertEquals("Incorrect ServiceType", "WCS", serviceIdentification.getServiceType()); + assertNotNull(serviceIdentification, "Service Identification is null"); + assertEquals("NONE", serviceIdentification.getFees(), "Incorrect Fees"); + assertEquals("WCS", serviceIdentification.getServiceType(), "Incorrect ServiceType"); List titles = serviceIdentification.getTitles(); - assertTrue("Titles is null", titles != null); - assertEquals("Incorrect Title count", 1, titles.size()); + assertTrue(titles != null, "Titles is null"); + assertEquals(1, titles.size(), "Incorrect Title count"); for (String title : titles) { - assertEquals("Incorrect Title", "Web Coverage Service", title); + assertEquals("Web Coverage Service", title, "Incorrect Title"); } List abstracts = serviceIdentification.getAbstracts(); - assertTrue("Abstracts is null", abstracts != null); - assertEquals("Incorrect Abstract count", 1, abstracts.size()); + assertTrue(abstracts != null, "Abstracts is null"); + assertEquals(1, abstracts.size(), "Incorrect Abstract count"); for (String abs : abstracts) { - assertTrue("Incorrect Abstract start", abs.startsWith("This server implements")); - assertTrue("Incorrect Abstract end", abs.endsWith("available on WMS also.")); + assertTrue(abs.startsWith("This server implements"), "Incorrect Abstract start"); + assertTrue(abs.endsWith("available on WMS also."), "Incorrect Abstract end"); } List keywords = serviceIdentification.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("WMS")); - assertTrue("Missing Keyword", keywords.contains("GEOSERVER")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("WMS"), "Missing Keyword"); + assertTrue(keywords.contains("GEOSERVER"), "Missing Keyword"); List serviceTypeVersions = serviceIdentification.getServiceTypeVersions(); - assertTrue("ServiceTypeVersions is null", serviceTypeVersions != null); - assertEquals("Incorrect ServiceTypeVersion count", 2, serviceTypeVersions.size()); - assertTrue("Missing Keyword", serviceTypeVersions.contains("1.1.0")); - assertTrue("Missing Keyword", serviceTypeVersions.contains("1.1.1")); + assertTrue(serviceTypeVersions != null, "ServiceTypeVersions is null"); + assertEquals(2, serviceTypeVersions.size(), "Incorrect ServiceTypeVersion count"); + assertTrue(serviceTypeVersions.contains("1.1.0"), "Missing Keyword"); + assertTrue(serviceTypeVersions.contains("1.1.1"), "Missing Keyword"); List accessConstraints = serviceIdentification.getAccessConstraints(); - assertTrue("AccessConstraints is null", accessConstraints != null); - assertEquals("Incorrect AccessConstraints count", 1, abstracts.size()); + assertTrue(accessConstraints != null, "AccessConstraints is null"); + assertEquals(1, abstracts.size(), "Incorrect AccessConstraints count"); for (String abs : accessConstraints) { - assertEquals("Incorrect AccessConstraint", "NONE", abs); + assertEquals("NONE", abs, "Incorrect AccessConstraint"); } OWSServiceProvider serviceProvider = caps.getServiceProvider(); - assertTrue("ServiceProvider is null", serviceProvider != null); - assertEquals("ProviderName is incorrect", "The ancient geographes INC", serviceProvider.getProviderName()); - assertEquals("ProviderSite is incorrect", "http://geoserver.org", serviceProvider.getProviderSite()); + assertTrue(serviceProvider != null, "ServiceProvider is null"); + assertEquals("The ancient geographes INC", serviceProvider.getProviderName(), "ProviderName is incorrect"); + assertEquals("http://geoserver.org", serviceProvider.getProviderSite(), "ProviderSite is incorrect"); OWSServiceContact serviceContact = serviceProvider.getServiceContact(); - assertTrue("ServiceContact is null", serviceContact != null); - assertEquals("IndividualName is incorrect", "Claudius Ptolomaeus", serviceContact.getIndividualName()); - assertEquals("PositionName is incorrect", "Chief geographer", serviceContact.getPositionName()); + assertTrue(serviceContact != null, "ServiceContact is null"); + assertEquals("Claudius Ptolomaeus", serviceContact.getIndividualName(), "IndividualName is incorrect"); + assertEquals("Chief geographer", serviceContact.getPositionName(), "PositionName is incorrect"); OWSContactInfo contactInfo = serviceContact.getContactInfo(); - assertTrue("ContactInfo is null", contactInfo != null); - assertEquals("OnlineResource is incorrect", "http://geoserver.org", contactInfo.getOnlineResource()); + assertTrue(contactInfo != null, "ContactInfo is null"); + assertEquals("http://geoserver.org", contactInfo.getOnlineResource(), "OnlineResource is incorrect"); OWSPhone phone = contactInfo.getPhone(); - assertTrue("Phone is null", phone != null); + assertTrue(phone != null, "Phone is null"); OWSAddress address = contactInfo.getAddress(); - assertTrue("Address is null", address != null); - assertEquals("City is incorrect", "Alexandria", address.getCity()); + assertTrue(address != null, "Address is null"); + assertEquals("Alexandria", address.getCity(), "City is incorrect"); List countries = address.getCountries(); - assertTrue("Countries is null", countries != null); - assertEquals("Incorrect Country count", 1, countries.size()); + assertTrue(countries != null, "Countries is null"); + assertEquals(1, countries.size(), "Incorrect Country count"); for (String country : countries) { - assertEquals("Incorrect Country", "Egypt", country); + assertEquals("Egypt", country, "Incorrect Country"); } List emails = address.getElectronicMailAddresses(); - assertTrue("ElectronicMailAddress is null", emails != null); - assertEquals("Incorrect ElectronicMailAddress count", 1, emails.size()); + assertTrue(emails != null, "ElectronicMailAddress is null"); + assertEquals(1, emails.size(), "Incorrect ElectronicMailAddress count"); for (String email : emails) { - assertEquals("Incorrect ElectronicMailAddress", "claudius.ptolomaeus@gmail.com", email); + assertEquals("claudius.ptolomaeus@gmail.com", email, "Incorrect ElectronicMailAddress"); } OWSOperationsMetadata operationsMetadata = caps.getOperationsMetadata(); - assertTrue("OperationsMetadata is null", operationsMetadata != null); + assertTrue(operationsMetadata != null, "OperationsMetadata is null"); List operations = operationsMetadata.getOperations(); - assertTrue("Operations is null", operations != null); - assertEquals("Incorrect Operation count", 3, operations.size()); + assertTrue(operations != null, "Operations is null"); + assertEquals(3, operations.size(), "Incorrect Operation count"); Set operationNames = new HashSet(3); for (OWSOperation operation : operations) { operationNames.add(operation.getName()); } - assertTrue("Missing Operation", operationNames.contains("GetCapabilities")); - assertTrue("Missing Operation", operationNames.contains("DescribeCoverage")); - assertTrue("Missing Operation", operationNames.contains("GetCoverage")); + assertTrue(operationNames.contains("GetCapabilities"), "Missing Operation"); + assertTrue(operationNames.contains("DescribeCoverage"), "Missing Operation"); + assertTrue(operationNames.contains("GetCoverage"), "Missing Operation"); for (OWSOperation operation : operations) { List dcps = operation.getDCPs(); - assertTrue("DCPs is null", dcps != null); - assertEquals("Incorrect DCP count", 2, dcps.size()); + assertTrue(dcps != null, "DCPs is null"); + assertEquals(2, dcps.size(), "Incorrect DCP count"); for (OWSDCP dcp : dcps) { - assertTrue("DCP HTTP is null", dcp.getHTTP() != null); + assertTrue(dcp.getHTTP() != null, "DCP HTTP is null"); } } String url = operationsMetadata.getGetOperationAddress("Get", "GetCapabilities"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); url = operationsMetadata.getGetOperationAddress("Post", "GetCapabilities"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); url = operationsMetadata.getGetOperationAddress("Get", "DescribeCoverage"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); url = operationsMetadata.getGetOperationAddress("Post", "DescribeCoverage"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); url = operationsMetadata.getGetOperationAddress("Get", "GetCoverage"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); url = operationsMetadata.getGetOperationAddress("Post", "GetCoverage"); - assertTrue("Get operation address is null", url != null); - assertEquals("Incorrect HTTP address", "http://10.0.1.198:8080/geoserver/wcs?", url); + assertTrue(url != null, "Get operation address is null"); + assertEquals("http://10.0.1.198:8080/geoserver/wcs?", url, "Incorrect HTTP address"); OWSOperation coverageOp = operationsMetadata.getOperation("GetCoverage"); List parameters = coverageOp.getParameters(); - assertTrue("Operation Parameters is null", parameters != null); - assertEquals("Operation Parameter count is incorrect", 1, parameters.size()); + assertTrue(parameters != null, "Operation Parameters is null"); + assertEquals(1, parameters.size(), "Operation Parameter count is incorrect"); for (OWSParameter parameter : parameters) { - assertTrue("Store parameter is missing", parameter.getName() != null); - assertEquals("Incorrect store value", "store", parameter.getName()); + assertTrue(parameter.getName() != null, "Store parameter is missing"); + assertEquals("store", parameter.getName(), "Incorrect store value"); List allowedValues = parameter.getAllowedValues(); - assertTrue("AllowedValues is null", allowedValues != null); - assertEquals("AllowedValues count is incorrect", 1, allowedValues.size()); + assertTrue(allowedValues != null, "AllowedValues is null"); + assertEquals(1, allowedValues.size(), "AllowedValues count is incorrect"); for (OWSAllowedValues avs : allowedValues) { List avals = avs.getValues(); - assertTrue("AllowedValues values is null", avals != null); - assertEquals("Allowed Values values count is incorrect", 2, avals.size()); - assertTrue("Missing allowed value", avals.contains("True")); - assertTrue("Missing allowed value", avals.contains("False")); + assertTrue(avals != null, "AllowedValues values is null"); + assertEquals(2, avals.size(), "Allowed Values values count is incorrect"); + assertTrue(avals.contains("True"), "Missing allowed value"); + assertTrue(avals.contains("False"), "Missing allowed value"); } } List constraints = operationsMetadata.getConstraints(); - assertTrue("Constraints is null", constraints != null); - assertEquals("Incorrect Constraint count", 1, constraints.size()); + assertTrue(constraints != null, "Constraints is null"); + assertEquals(1, constraints.size(), "Incorrect Constraint count"); for (OWSConstraint constraint : constraints) { - assertEquals("Incorrect Constraint", "PostEncoding", constraint.getName()); + assertEquals("PostEncoding", constraint.getName(), "Incorrect Constraint"); List allowedValues = constraint.getAllowedValues(); - assertTrue("AllowedValues is null", allowedValues != null); - assertEquals("AllowedValues count is incorrect", 1, allowedValues.size()); + assertTrue(allowedValues != null, "AllowedValues is null"); + assertEquals(1, allowedValues.size(), "AllowedValues count is incorrect"); for (OWSAllowedValues avs : allowedValues) { List avals = avs.getValues(); - assertTrue("AllowedValues values is null", avals != null); - assertEquals("Allowed Values values count is incorrect", 1, avals.size()); - assertTrue("Missing allowed value", avals.contains("XML")); + assertTrue(avals != null, "AllowedValues values is null"); + assertEquals(1, avals.size(), "Allowed Values values count is incorrect"); + assertTrue(avals.contains("XML"), "Missing allowed value"); } } WCSContents contents = caps.getContents(); - assertTrue("WCS Contents is missing", contents != null); + assertTrue(contents != null, "WCS Contents is missing"); List coverageSummaries = contents.getCoverageSummaries(); - assertTrue("WCS CoverageSummarys are missing", coverageSummaries != null); - assertEquals("WCS CoverageSummarys count is incorrect", 7, coverageSummaries.size()); + assertTrue(coverageSummaries != null, "WCS CoverageSummarys are missing"); + assertEquals(7, coverageSummaries.size(), "WCS CoverageSummarys count is incorrect"); Set identifiers = new HashSet(coverageSummaries.size()); for (WCSCoverageSummary summary : coverageSummaries) { identifiers.add(summary.getIdentifier()); } - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("Arc_Sample")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("aster_v2")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("FAAChartsCroppedReprojected")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("NASA_SRTM30_900m_Tiled")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("Img_Sample")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("mosaic")); - assertTrue("Missing CoverageSummary Identifier", identifiers.contains("sfdem")); + assertTrue(identifiers.contains("Arc_Sample"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("aster_v2"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("FAAChartsCroppedReprojected"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("NASA_SRTM30_900m_Tiled"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("Img_Sample"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("mosaic"), "Missing CoverageSummary Identifier"); + assertTrue(identifiers.contains("sfdem"), "Missing CoverageSummary Identifier"); for (WCSCoverageSummary summary : coverageSummaries) { if (summary.getIdentifier().equals("Arc_Sample")) { - assertEquals("CoverageSummary Title is incorrect", "A sample ArcGrid file", summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from arcGridSample", - summary.getAbstract()); + assertEquals("A sample ArcGrid file", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from arcGridSample", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("arcGridSample")); - assertTrue("Missing Keyword", keywords.contains("arcGridSample_Coverage")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("arcGridSample"), "Missing Keyword"); + assertTrue(keywords.contains("arcGridSample_Coverage"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-180.0 -90.0", bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "180.0 90.0", bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-180.0 -90.0", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("180.0 90.0", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("aster_v2")) { - assertEquals("CoverageSummary Title is incorrect", "ASTER", summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from ImageMosaic", - summary.getAbstract()); + assertEquals("ASTER", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from ImageMosaic", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("ImageMosaic")); - assertTrue("Missing Keyword", keywords.contains("ASTER")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("ImageMosaic"), "Missing Keyword"); + assertTrue(keywords.contains("ASTER"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-180.0001388888889 -83.0001388888889", - bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "180.00013888888887 83.00013888888888", - bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-180.0001388888889 -83.0001388888889", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("180.00013888888887 83.00013888888888", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("FAAChartsCroppedReprojected")) { - assertEquals("CoverageSummary Title is incorrect", "FAAChartsCroppedReprojected", - summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from ImageMosaic", - summary.getAbstract()); + assertEquals("FAAChartsCroppedReprojected", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from ImageMosaic", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("ImageMosaic")); - assertTrue("Missing Keyword", keywords.contains("FAAChartsCroppedReprojected")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("ImageMosaic"), "Missing Keyword"); + assertTrue(keywords.contains("FAAChartsCroppedReprojected"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-173.4897609604564 50.896520942672375", - bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "178.65474058869506 72.33574978977076", - bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-173.4897609604564 50.896520942672375", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("178.65474058869506 72.33574978977076", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("NASA_SRTM30_900m_Tiled")) { - assertEquals("CoverageSummary Title is incorrect", "NASA_SRTM30_900m_Tiled", summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from ImageMosaic", - summary.getAbstract()); + assertEquals("NASA_SRTM30_900m_Tiled", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from ImageMosaic", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("ImageMosaic")); - assertTrue("Missing Keyword", keywords.contains("NASA_SRTM30_900m_Tiled")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("ImageMosaic"), "Missing Keyword"); + assertTrue(keywords.contains("NASA_SRTM30_900m_Tiled"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-180.0 -90.0", bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "180.0 90.0", bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-180.0 -90.0", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("180.0 90.0", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("Img_Sample")) { - assertEquals("CoverageSummary Title is incorrect", "North America sample imagery", - summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "A very rough imagery of North America", - summary.getAbstract()); + assertEquals("North America sample imagery", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("A very rough imagery of North America", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("worldImageSample")); - assertTrue("Missing Keyword", keywords.contains("worldImageSample_Coverage")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("worldImageSample"), "Missing Keyword"); + assertTrue(keywords.contains("worldImageSample_Coverage"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-130.85168 20.7052", bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "-62.0054 54.1141", bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-130.85168 20.7052", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("-62.0054 54.1141", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("mosaic")) { - assertEquals("CoverageSummary Title is incorrect", "mosaic", summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from ImageMosaic", - summary.getAbstract()); + assertEquals("mosaic", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from ImageMosaic", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("ImageMosaic")); - assertTrue("Missing Keyword", keywords.contains("mosaic")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("ImageMosaic"), "Missing Keyword"); + assertTrue(keywords.contains("mosaic"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "6.346 36.492", bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "20.83 46.591", bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("6.346 36.492", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("20.83 46.591", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else if (summary.getIdentifier().equals("sfdem")) { - assertEquals("CoverageSummary Title is incorrect", - "sfdem is a Tagged Image File Format with Geographic information", summary.getTitle()); - assertEquals("CoverageSummary Abstract is incorrect", "Generated from sfdem", - summary.getAbstract()); + assertEquals("sfdem is a Tagged Image File Format with Geographic information", summary.getTitle(), "CoverageSummary Title is incorrect"); + assertEquals("Generated from sfdem", summary.getAbstract(), "CoverageSummary Abstract is incorrect"); keywords = summary.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect Keyword count", 3, keywords.size()); - assertTrue("Missing Keyword", keywords.contains("WCS")); - assertTrue("Missing Keyword", keywords.contains("sfdem")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect Keyword count"); + assertTrue(keywords.contains("WCS"), "Missing Keyword"); + assertTrue(keywords.contains("sfdem"), "Missing Keyword"); OWSWGS84BoundingBox bbox = summary.getBoundingBox(); - assertTrue("BoundingBox is null", bbox != null); - assertEquals("LowerCorner is incorrect", "-103.87108701853181 44.370187074132616", - bbox.getLowerCorner()); - assertEquals("UpperCorner is incorrect", "-103.62940739432703 44.5016011535299", - bbox.getUpperCorner()); + assertTrue(bbox != null, "BoundingBox is null"); + assertEquals("-103.87108701853181 44.370187074132616", bbox.getLowerCorner(), "LowerCorner is incorrect"); + assertEquals("-103.62940739432703 44.5016011535299", bbox.getUpperCorner(), "UpperCorner is incorrect"); } else { - assertTrue("Unrecognized WCS CoverageSummary", false); + assertTrue(false, "Unrecognized WCS CoverageSummary"); } } } @@ -698,25 +661,25 @@ private static void checkRequestDescription(WCS100RequestDescription requestDesc { List dcpTypes = requestDescription.getDCPTypes(); - assertNotNull("DCPTypes is null for " + requestDescription.getRequestName(), dcpTypes); - assertEquals("Incorrect DCPTypes count for " + requestDescription.getRequestName(), 2, dcpTypes.size()); + assertNotNull(dcpTypes, "DCPTypes is null for " + requestDescription.getRequestName()); + assertEquals(2, dcpTypes.size(), "Incorrect DCPTypes count for " + requestDescription.getRequestName()); String get = null; String post = null; for (WCS100DCPType dcpType : dcpTypes) { WCS100HTTP http = dcpType.getHTTP(); - assertNotNull("HTTP is null for request name " + requestDescription.getRequestName(), http); + assertNotNull(http, "HTTP is null for request name " + requestDescription.getRequestName()); if (http.getGetAddress() != null) get = http.getGetAddress(); if (http.getPostAddress() != null) post = http.getPostAddress(); } - assertNotNull("Get address is null for request name " + requestDescription.getRequestName(), get); - assertNotNull("Post address is null for request name " + requestDescription.getRequestName(), post); + assertNotNull(get, "Get address is null for request name " + requestDescription.getRequestName()); + assertNotNull(post, "Post address is null for request name " + requestDescription.getRequestName()); - assertEquals("Get address is incorrect for " + requestDescription.getRequestName(), url, get); - assertEquals("Post address is incorrect for " + requestDescription.getRequestName(), url, post); + assertEquals(url, get, "Get address is incorrect for " + requestDescription.getRequestName()); + assertEquals(url, post, "Post address is incorrect for " + requestDescription.getRequestName()); } } diff --git a/test/gov/nasa/worldwind/ogc/wcs/WCSDescribeCoverageParsingTest.java b/test/gov/nasa/worldwind/ogc/wcs/WCSDescribeCoverageParsingTest.java index 2416cd05a9..50808848cd 100644 --- a/test/gov/nasa/worldwind/ogc/wcs/WCSDescribeCoverageParsingTest.java +++ b/test/gov/nasa/worldwind/ogc/wcs/WCSDescribeCoverageParsingTest.java @@ -30,16 +30,12 @@ import gov.nasa.worldwind.ogc.gml.*; import gov.nasa.worldwind.ogc.wcs.wcs100.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.util.List; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class WCSDescribeCoverageParsingTest { @Test @@ -57,124 +53,115 @@ public void testParsing001() } List coverageOfferings = caps.getCoverageOfferings(); - assertNotNull("CoverageOfferings is null", coverageOfferings); - assertEquals("Incorrect coverage offering count", 1, coverageOfferings.size()); + assertNotNull(coverageOfferings, "CoverageOfferings is null"); + assertEquals(1, coverageOfferings.size(), "Incorrect coverage offering count"); WCS100CoverageOffering coverage = coverageOfferings.get(0); - assertNotNull("CoverageOffering is null", coverage); - assertNotNull("CoverageOffering name is null", coverage.getName()); - assertEquals("Incorrect CoverageOffering name", "WW:NASA_SRTM30_900m_Tiled", coverage.getName()); - assertNotNull("CoverageOffering label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOffering label", "NASA_SRTM30_900m_Tiled", coverage.getLabel()); + assertNotNull(coverage, "CoverageOffering is null"); + assertNotNull(coverage.getName(), "CoverageOffering name is null"); + assertEquals("WW:NASA_SRTM30_900m_Tiled", coverage.getName(), "Incorrect CoverageOffering name"); + assertNotNull(coverage.getLabel(), "CoverageOffering label is null"); + assertEquals("NASA_SRTM30_900m_Tiled", coverage.getLabel(), "Incorrect CoverageOffering label"); WCS100LonLatEnvelope lonLatEnvelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope is null", lonLatEnvelope); - assertNotNull("LonLatEnvelope positions is null", lonLatEnvelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope SRS", "urn:ogc:def:crs:OGC:1.3:CRS84", lonLatEnvelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope position count", 2, lonLatEnvelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope position 0", "-180.0 -90.0", - lonLatEnvelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope position 1", "180.0 90.0", - lonLatEnvelope.getPositions().get(1).getPosString()); + assertNotNull(lonLatEnvelope, "LonLatEnvelope is null"); + assertNotNull(lonLatEnvelope.getPositions(), "LonLatEnvelope positions is null"); + assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", lonLatEnvelope.getSRSName(), "Incorrect LonLatEnvelope SRS"); + assertEquals(2, lonLatEnvelope.getPositions().size(), "Incorrect LonLatEnvelope position count"); + assertEquals("-180.0 -90.0", lonLatEnvelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope position 0"); + assertEquals("180.0 90.0", lonLatEnvelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope position 1"); List keywords = coverage.getKeywords(); - assertTrue("Keywords is null", keywords != null); - assertEquals("Incorrect keyword count", 3, keywords.size()); - assertTrue("Missing keyword", keywords.contains("WCS")); - assertTrue("Missing keyword", keywords.contains("ImageMosaic")); - assertTrue("Missing keyword", keywords.contains("NASA_SRTM30_900m_Tiled")); + assertTrue(keywords != null, "Keywords is null"); + assertEquals(3, keywords.size(), "Incorrect keyword count"); + assertTrue(keywords.contains("WCS"), "Missing keyword"); + assertTrue(keywords.contains("ImageMosaic"), "Missing keyword"); + assertTrue(keywords.contains("NASA_SRTM30_900m_Tiled"), "Missing keyword"); WCS100DomainSet domainSet = coverage.getDomainSet(); - assertNotNull("DomainSet is null", domainSet); + assertNotNull(domainSet, "DomainSet is null"); WCS100SpatialDomain spatialDomain = domainSet.getSpatialDomain(); - assertNotNull("SpatialDomain is null", spatialDomain); + assertNotNull(spatialDomain, "SpatialDomain is null"); List envelopes = spatialDomain.getEnvelopes(); - assertNotNull("Envelope is null", envelopes); - assertEquals("Incorrect envelope count", 1, envelopes.size()); + assertNotNull(envelopes, "Envelope is null"); + assertEquals(1, envelopes.size(), "Incorrect envelope count"); GMLEnvelope envelope = envelopes.get(0); - assertEquals("Envelope position 0 is incorrect", "-180.0 -90.0", - envelope.getPositions().get(0).getPosString()); - assertEquals("Envelope position 1 is incorrect", "180.0 90.0", - envelope.getPositions().get(1).getPosString()); + assertEquals("-180.0 -90.0", envelope.getPositions().get(0).getPosString(), "Envelope position 0 is incorrect"); + assertEquals("180.0 90.0", envelope.getPositions().get(1).getPosString(), "Envelope position 1 is incorrect"); List rectifiedGrids = spatialDomain.getRectifiedGrids(); - assertNotNull("RectifiedGrid is null", rectifiedGrids); - assertEquals("Incorrect RectifiedGrid count", 1, rectifiedGrids.size()); + assertNotNull(rectifiedGrids, "RectifiedGrid is null"); + assertEquals(1, rectifiedGrids.size(), "Incorrect RectifiedGrid count"); GMLRectifiedGrid rGrid = rectifiedGrids.get(0); GMLLimits limits = rGrid.getLimits(); - assertNotNull("Limits is null", limits); + assertNotNull(limits, "Limits is null"); List gridEnvelopes = limits.getGridEnvelopes(); - assertNotNull("GridEnvelope is null", gridEnvelopes); - assertEquals("Incorrect GridEnvelope count", 1, gridEnvelopes.size()); - assertEquals("Low limit is incorrect", "0 0", gridEnvelopes.get(0).getLow()); - assertEquals("High limit is incorrect", "43199 21599", gridEnvelopes.get(0).getHigh()); + assertNotNull(gridEnvelopes, "GridEnvelope is null"); + assertEquals(1, gridEnvelopes.size(), "Incorrect GridEnvelope count"); + assertEquals("0 0", gridEnvelopes.get(0).getLow(), "Low limit is incorrect"); + assertEquals("43199 21599", gridEnvelopes.get(0).getHigh(), "High limit is incorrect"); List axisNames = rGrid.getAxisNames(); - assertNotNull("AxisNames is null", axisNames); - assertEquals("Incorrect AxisNames count", 2, axisNames.size()); - assertEquals("Incorrect first axis name 0", "x", axisNames.get(0)); - assertEquals("Incorrect second axis name 0", "y", axisNames.get(1)); + assertNotNull(axisNames, "AxisNames is null"); + assertEquals(2, axisNames.size(), "Incorrect AxisNames count"); + assertEquals("x", axisNames.get(0), "Incorrect first axis name 0"); + assertEquals("y", axisNames.get(1), "Incorrect second axis name 0"); GMLOrigin origin = rGrid.getOrigin(); - assertNotNull("Origin is null", origin); - assertEquals("Incorrect origin values", "-179.99583333333334 89.99583333333334", - origin.getPos().getPosString()); + assertNotNull(origin, "Origin is null"); + assertEquals("-179.99583333333334 89.99583333333334", origin.getPos().getPosString(), "Incorrect origin values"); List offsetVectors = rGrid.getOffsetVectorStrings(); - assertNotNull("OffsetVectors is null", offsetVectors); - assertEquals("Incorrect offsetVector count", 2, offsetVectors.size()); - assertEquals("Incorrect first offset vector", "0.008333333333333333 0.0", offsetVectors.get(0)); - assertEquals("Incorrect second offset vector", "0.0 -0.008333333333333333", offsetVectors.get(1)); + assertNotNull(offsetVectors, "OffsetVectors is null"); + assertEquals(2, offsetVectors.size(), "Incorrect offsetVector count"); + assertEquals("0.008333333333333333 0.0", offsetVectors.get(0), "Incorrect first offset vector"); + assertEquals("0.0 -0.008333333333333333", offsetVectors.get(1), "Incorrect second offset vector"); WCS100RangeSetHolder rangeSetHolder = coverage.getRangeSet(); - assertNotNull("RangeSetHolder is null", rangeSetHolder); + assertNotNull(rangeSetHolder, "RangeSetHolder is null"); WCS100RangeSet rangeSet = rangeSetHolder.getRangeSet(); - assertNotNull("RangeSet is null", rangeSet); - assertEquals("RangeSet name is incorrect", "NASA_SRTM30_900m_Tiled", rangeSet.getName()); - assertEquals("RangeSet label is incorrect", "NASA_SRTM30_900m_Tiled", rangeSet.getLabel()); + assertNotNull(rangeSet, "RangeSet is null"); + assertEquals("NASA_SRTM30_900m_Tiled", rangeSet.getName(), "RangeSet name is incorrect"); + assertEquals("NASA_SRTM30_900m_Tiled", rangeSet.getLabel(), "RangeSet label is incorrect"); List axisDescriptionHolders = rangeSet.getAxisDescriptions(); - assertNotNull("axisDescription is null", axisDescriptionHolders); - assertEquals("axisDescription count incorrect", 1, axisDescriptionHolders.size()); + assertNotNull(axisDescriptionHolders, "axisDescription is null"); + assertEquals(1, axisDescriptionHolders.size(), "axisDescription count incorrect"); WCS100AxisDescription axisDescription = axisDescriptionHolders.get(0).getAxisDescription(); - assertNotNull("AxisDescription is null", axisDescription); - assertEquals("AxisDescription name is incorrect", "Band", axisDescription.getName()); - assertEquals("AxisDescription label is incorrect", "Band", axisDescription.getLabel()); + assertNotNull(axisDescription, "AxisDescription is null"); + assertEquals("Band", axisDescription.getName(), "AxisDescription name is incorrect"); + assertEquals("Band", axisDescription.getLabel(), "AxisDescription label is incorrect"); WCS100Values values = axisDescription.getValues(); - assertNotNull("Values is null", values); + assertNotNull(values, "Values is null"); List singleValues = values.getSingleValues(); - assertNotNull("SingleValues is null", singleValues); - assertEquals("Incorrect singleValues count", 1, singleValues.size()); - assertEquals("Incorrect singleValue", 1.0, singleValues.get(0).getSingleValue(), 0.0); + assertNotNull(singleValues, "SingleValues is null"); + assertEquals(1, singleValues.size(), "Incorrect singleValues count"); + assertEquals(1.0, singleValues.get(0).getSingleValue(), 0.0, "Incorrect singleValue"); WCS100SupportedFormats supportedFormats = coverage.getSupportedFormats(); - assertNotNull("SuppotedFormats is null", supportedFormats); - assertEquals("SupportedFormats count is incorrect", 8, supportedFormats.getStrings().size()); - assertTrue("Missing format", supportedFormats.getStrings().contains("ArcGrid")); - assertTrue("Missing format", supportedFormats.getStrings().contains("GeoTIFF")); - assertTrue("Missing format", supportedFormats.getStrings().contains("GIF")); - assertTrue("Missing format", supportedFormats.getStrings().contains("Gtopo30")); - assertTrue("Missing format", supportedFormats.getStrings().contains("ImageMosaic")); - assertTrue("Missing format", supportedFormats.getStrings().contains("JPEG")); - assertTrue("Missing format", supportedFormats.getStrings().contains("PNG")); - assertTrue("Missing format", supportedFormats.getStrings().contains("TIFF")); - assertEquals("Supported formats nativeFormat is incorrect", "ImageMosaic", - supportedFormats.getNativeFormat()); + assertNotNull(supportedFormats, "SuppotedFormats is null"); + assertEquals(8, supportedFormats.getStrings().size(), "SupportedFormats count is incorrect"); + assertTrue(supportedFormats.getStrings().contains("ArcGrid"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("GeoTIFF"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("GIF"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("Gtopo30"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("ImageMosaic"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("JPEG"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("PNG"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("TIFF"), "Missing format"); + assertEquals("ImageMosaic", supportedFormats.getNativeFormat(), "Supported formats nativeFormat is incorrect"); WCS100SupportedCRSs supportedCRSs = coverage.getSupportedCRSs(); - assertNotNull("SupportedCRSs is null", supportedCRSs); - assertNotNull("SupportedCRSs requestResponses is null", supportedCRSs.getRequestResponseCRSs()); - assertEquals("SupportedCRSs requestResponse count is incorrect", 1, - supportedCRSs.getRequestResponseCRSs().size()); - assertEquals("RequestResponse value is incorrect", "EPSG:4326", - supportedCRSs.getRequestResponseCRSs().get(0)); + assertNotNull(supportedCRSs, "SupportedCRSs is null"); + assertNotNull(supportedCRSs.getRequestResponseCRSs(), "SupportedCRSs requestResponses is null"); + assertEquals(1, supportedCRSs.getRequestResponseCRSs().size(), "SupportedCRSs requestResponse count is incorrect"); + assertEquals("EPSG:4326", supportedCRSs.getRequestResponseCRSs().get(0), "RequestResponse value is incorrect"); WCS100SupportedInterpolations supportedInterpolations = coverage.getSupportedInterpolations(); - assertNotNull("SupportedInterpolations is null", supportedInterpolations); - assertEquals("SupportedInterpolations count is incorrect", 3, supportedInterpolations.getStrings().size()); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("nearest neighbor")); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("bilinear")); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("bicubic")); - assertEquals("Supported Interpolations default is incorrect", "nearest neighbor", - supportedInterpolations.getDefault()); + assertNotNull(supportedInterpolations, "SupportedInterpolations is null"); + assertEquals(3, supportedInterpolations.getStrings().size(), "SupportedInterpolations count is incorrect"); + assertTrue(supportedInterpolations.getStrings().contains("nearest neighbor"), "Missing interpolation"); + assertTrue(supportedInterpolations.getStrings().contains("bilinear"), "Missing interpolation"); + assertTrue(supportedInterpolations.getStrings().contains("bicubic"), "Missing interpolation"); + assertEquals("nearest neighbor", supportedInterpolations.getDefault(), "Supported Interpolations default is incorrect"); } @Test @@ -192,132 +179,119 @@ public void testParsing002() } List coverageOfferings = caps.getCoverageOfferings(); - assertNotNull("CoverageOfferings is null", coverageOfferings); - assertEquals("Incorrect coverage offering count", 1, coverageOfferings.size()); + assertNotNull(coverageOfferings, "CoverageOfferings is null"); + assertEquals(1, coverageOfferings.size(), "Incorrect coverage offering count"); WCS100CoverageOffering coverage = coverageOfferings.get(0); - assertNotNull("CoverageOffering is null", coverage); - assertNotNull("CoverageOffering name is null", coverage.getName()); - assertEquals("Incorrect CoverageOffering name", "1", coverage.getName()); - assertNotNull("CoverageOffering label is null", coverage.getLabel()); - assertEquals("Incorrect CoverageOffering label", "dted0_1", coverage.getLabel()); + assertNotNull(coverage, "CoverageOffering is null"); + assertNotNull(coverage.getName(), "CoverageOffering name is null"); + assertEquals("1", coverage.getName(), "Incorrect CoverageOffering name"); + assertNotNull(coverage.getLabel(), "CoverageOffering label is null"); + assertEquals("dted0_1", coverage.getLabel(), "Incorrect CoverageOffering label"); WCS100LonLatEnvelope lonLatEnvelope = coverage.getLonLatEnvelope(); - assertNotNull("LonLatEnvelope is null", lonLatEnvelope); - assertNotNull("LonLatEnvelope positions is null", lonLatEnvelope.getPositions()); - assertEquals("Incorrect LonLatEnvelope SRS", "WGS84(DD)", lonLatEnvelope.getSRSName()); - assertEquals("Incorrect LonLatEnvelope position count", 2, lonLatEnvelope.getPositions().size()); - assertEquals("Incorrect LonLatEnvelope position 0", "-179.99999999999991 -89.999999999999943", - lonLatEnvelope.getPositions().get(0).getPosString()); - assertEquals("Incorrect LonLatEnvelope position 1", "180.00000000000003 84.00416666700005", - lonLatEnvelope.getPositions().get(1).getPosString()); + assertNotNull(lonLatEnvelope, "LonLatEnvelope is null"); + assertNotNull(lonLatEnvelope.getPositions(), "LonLatEnvelope positions is null"); + assertEquals("WGS84(DD)", lonLatEnvelope.getSRSName(), "Incorrect LonLatEnvelope SRS"); + assertEquals(2, lonLatEnvelope.getPositions().size(), "Incorrect LonLatEnvelope position count"); + assertEquals("-179.99999999999991 -89.999999999999943", lonLatEnvelope.getPositions().get(0).getPosString(), "Incorrect LonLatEnvelope position 0"); + assertEquals("180.00000000000003 84.00416666700005", lonLatEnvelope.getPositions().get(1).getPosString(), "Incorrect LonLatEnvelope position 1"); WCS100DomainSet domainSet = coverage.getDomainSet(); - assertNotNull("DomainSet is null", domainSet); + assertNotNull(domainSet, "DomainSet is null"); WCS100SpatialDomain spatialDomain = domainSet.getSpatialDomain(); - assertNotNull("SpatialDomain is null", spatialDomain); + assertNotNull(spatialDomain, "SpatialDomain is null"); List envelopes = spatialDomain.getEnvelopes(); - assertNotNull("Envelope is null", envelopes); - assertEquals("Incorrect envelope count", 1, envelopes.size()); + assertNotNull(envelopes, "Envelope is null"); + assertEquals(1, envelopes.size(), "Incorrect envelope count"); GMLEnvelope envelope = envelopes.get(0); - assertNotNull("Envelope srsName is null", envelope.getSRSName()); - assertEquals("Envelope srsName is incorrect", "EPSG:4326", envelope.getSRSName()); - assertEquals("Envelope position 0 is incorrect", "-179.99999999999991 -89.999999999999943", - envelope.getPositions().get(0).getPosString()); - assertEquals("Envelope position 1 is incorrect", "180.00000000000003 84.00416666700005", - envelope.getPositions().get(1).getPosString()); - assertNotNull("Envelope position 0 dimension missing", envelope.getPositions().get(0).getDimension()); - assertNotNull("Envelope position 1 dimension missing", envelope.getPositions().get(1).getDimension()); - assertEquals("Envelope position 0 dimension is incorrect", "2", - envelope.getPositions().get(0).getDimension()); - assertEquals("Envelope position 1 dimension is incorrect", "2", - envelope.getPositions().get(1).getDimension()); + assertNotNull(envelope.getSRSName(), "Envelope srsName is null"); + assertEquals("EPSG:4326", envelope.getSRSName(), "Envelope srsName is incorrect"); + assertEquals("-179.99999999999991 -89.999999999999943", envelope.getPositions().get(0).getPosString(), "Envelope position 0 is incorrect"); + assertEquals("180.00000000000003 84.00416666700005", envelope.getPositions().get(1).getPosString(), "Envelope position 1 is incorrect"); + assertNotNull(envelope.getPositions().get(0).getDimension(), "Envelope position 0 dimension missing"); + assertNotNull(envelope.getPositions().get(1).getDimension(), "Envelope position 1 dimension missing"); + assertEquals("2", envelope.getPositions().get(0).getDimension(), "Envelope position 0 dimension is incorrect"); + assertEquals("2", envelope.getPositions().get(1).getDimension(), "Envelope position 1 dimension is incorrect"); List rectifiedGrids = spatialDomain.getRectifiedGrids(); - assertNotNull("RectifiedGrid is null", rectifiedGrids); - assertEquals("Incorrect RectifiedGrid count", 1, rectifiedGrids.size()); + assertNotNull(rectifiedGrids, "RectifiedGrid is null"); + assertEquals(1, rectifiedGrids.size(), "Incorrect RectifiedGrid count"); GMLRectifiedGrid rGrid = rectifiedGrids.get(0); GMLLimits limits = rGrid.getLimits(); - assertNotNull("Limits is null", limits); + assertNotNull(limits, "Limits is null"); List gridEnvelopes = limits.getGridEnvelopes(); - assertNotNull("GridEnvelope is null", gridEnvelopes); - assertEquals("Incorrect GridEnvelope count", 1, gridEnvelopes.size()); - assertEquals("Low limit is incorrect", "0 0", gridEnvelopes.get(0).getLow()); - assertEquals("High limit is incorrect", "43199 20880", gridEnvelopes.get(0).getHigh()); + assertNotNull(gridEnvelopes, "GridEnvelope is null"); + assertEquals(1, gridEnvelopes.size(), "Incorrect GridEnvelope count"); + assertEquals("0 0", gridEnvelopes.get(0).getLow(), "Low limit is incorrect"); + assertEquals("43199 20880", gridEnvelopes.get(0).getHigh(), "High limit is incorrect"); List axisNames = rGrid.getAxisNames(); - assertNotNull("AxisNames is null", axisNames); - assertEquals("Incorrect AxisNames count", 2, axisNames.size()); - assertEquals("Incorrect first axis name 0", "Raster_Pixel_Columns(X-axis)", axisNames.get(0)); - assertEquals("Incorrect second axis name 0", "Raster_Pixel_Rows(Y-axis)", axisNames.get(1)); + assertNotNull(axisNames, "AxisNames is null"); + assertEquals(2, axisNames.size(), "Incorrect AxisNames count"); + assertEquals("Raster_Pixel_Columns(X-axis)", axisNames.get(0), "Incorrect first axis name 0"); + assertEquals("Raster_Pixel_Rows(Y-axis)", axisNames.get(1), "Incorrect second axis name 0"); GMLOrigin origin = rGrid.getOrigin(); - assertNotNull("Origin is null", origin); - assertEquals("Incorrect origin values", "-179.99583333333325 84.000000100105098", - origin.getPos().getPosString()); + assertNotNull(origin, "Origin is null"); + assertEquals("-179.99583333333325 84.000000100105098", origin.getPos().getPosString(), "Incorrect origin values"); List offsetVectors = rGrid.getOffsetVectorStrings(); - assertNotNull("OffsetVectors is null", offsetVectors); - assertEquals("Incorrect offsetVector count", 2, offsetVectors.size()); - assertEquals("Incorrect first offset vector", "0.0083333333333333315 0", offsetVectors.get(0)); - assertEquals("Incorrect second offset vector", "0 -0.0083331337899046985", offsetVectors.get(1)); + assertNotNull(offsetVectors, "OffsetVectors is null"); + assertEquals(2, offsetVectors.size(), "Incorrect offsetVector count"); + assertEquals("0.0083333333333333315 0", offsetVectors.get(0), "Incorrect first offset vector"); + assertEquals("0 -0.0083331337899046985", offsetVectors.get(1), "Incorrect second offset vector"); WCS100RangeSetHolder rangeSetHolder = coverage.getRangeSet(); - assertNotNull("RangeSetHolder is null", rangeSetHolder); + assertNotNull(rangeSetHolder, "RangeSetHolder is null"); WCS100RangeSet rangeSet = rangeSetHolder.getRangeSet(); - assertNotNull("RangeSet is null", rangeSet); - assertEquals("RangeSet name is incorrect", "RangeSet_1", rangeSet.getName()); - assertEquals("RangeSet label is incorrect", "dted0_1 RangeSet", rangeSet.getLabel()); + assertNotNull(rangeSet, "RangeSet is null"); + assertEquals("RangeSet_1", rangeSet.getName(), "RangeSet name is incorrect"); + assertEquals("dted0_1 RangeSet", rangeSet.getLabel(), "RangeSet label is incorrect"); List axisDescriptionHolders = rangeSet.getAxisDescriptions(); - assertNotNull("axisDescription is null", axisDescriptionHolders); - assertEquals("axisDescription count incorrect", 1, axisDescriptionHolders.size()); + assertNotNull(axisDescriptionHolders, "axisDescription is null"); + assertEquals(1, axisDescriptionHolders.size(), "axisDescription count incorrect"); WCS100AxisDescription axisDescription = axisDescriptionHolders.get(0).getAxisDescription(); - assertNotNull("AxisDescription is null", axisDescription); - assertEquals("AxisDescription name is incorrect", "Band", axisDescription.getName()); - assertEquals("AxisDescription label is incorrect", "Band Numbers", axisDescription.getLabel()); + assertNotNull(axisDescription, "AxisDescription is null"); + assertEquals("Band", axisDescription.getName(), "AxisDescription name is incorrect"); + assertEquals("Band Numbers", axisDescription.getLabel(), "AxisDescription label is incorrect"); WCS100Values values = axisDescription.getValues(); - assertNotNull("Values is null", values); + assertNotNull(values, "Values is null"); List singleValues = values.getSingleValues(); - assertNotNull("SingleValues is null", singleValues); - assertEquals("Incorrect singleValues count", 1, singleValues.size()); - assertEquals("Incorrect singleValue", 1.0, singleValues.get(0).getSingleValue(), 0.0); + assertNotNull(singleValues, "SingleValues is null"); + assertEquals(1, singleValues.size(), "Incorrect singleValues count"); + assertEquals(1.0, singleValues.get(0).getSingleValue(), 0.0, "Incorrect singleValue"); WCS100Values nullValues = rangeSet.getNullValues(); - assertNotNull("NullValues is null", nullValues); + assertNotNull(nullValues, "NullValues is null"); singleValues = nullValues.getSingleValues(); - assertNotNull("NullValues SingleValues is null", nullValues); - assertEquals("NullValues Incorrect singleValues count", 1, singleValues.size()); - assertEquals("NullValues Incorrect singleValue", 32767.0, singleValues.get(0).getSingleValue(), 0.0); + assertNotNull(nullValues, "NullValues SingleValues is null"); + assertEquals(1, singleValues.size(), "NullValues Incorrect singleValues count"); + assertEquals(32767.0, singleValues.get(0).getSingleValue(), 0.0, "NullValues Incorrect singleValue"); WCS100SupportedFormats supportedFormats = coverage.getSupportedFormats(); - assertNotNull("SuppotedFormats is null", supportedFormats); - assertEquals("SupportedFormats count is incorrect", 4, supportedFormats.getStrings().size()); - assertTrue("Missing format", supportedFormats.getStrings().contains("GeoTIFF")); - assertTrue("Missing format", supportedFormats.getStrings().contains("NITF")); - assertTrue("Missing format", supportedFormats.getStrings().contains("HDF")); - assertTrue("Missing format", supportedFormats.getStrings().contains("JPEG2000")); - assertEquals("Supported formats nativeFormat is incorrect", "GeoTIFF", - supportedFormats.getNativeFormat()); + assertNotNull(supportedFormats, "SuppotedFormats is null"); + assertEquals(4, supportedFormats.getStrings().size(), "SupportedFormats count is incorrect"); + assertTrue(supportedFormats.getStrings().contains("GeoTIFF"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("NITF"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("HDF"), "Missing format"); + assertTrue(supportedFormats.getStrings().contains("JPEG2000"), "Missing format"); + assertEquals("GeoTIFF", supportedFormats.getNativeFormat(), "Supported formats nativeFormat is incorrect"); WCS100SupportedCRSs supportedCRSs = coverage.getSupportedCRSs(); - assertNotNull("SupportedCRSs is null", supportedCRSs); - assertNotNull("SupportedCRSs requestResponses is null", supportedCRSs.getRequestResponseCRSs()); - assertEquals("SupportedCRSs requestResponse count is incorrect", 1, - supportedCRSs.getRequestResponseCRSs().size()); - assertEquals("RequestResponse value is incorrect", "EPSG:4326", - supportedCRSs.getRequestResponseCRSs().get(0)); - assertNotNull("SupportedCRSs nativeCRSs is null", supportedCRSs.getNativeCRSs()); - assertEquals("SupportedCRSs nativeCRSs count is incorrect", 1, - supportedCRSs.getRequestResponseCRSs().size()); - assertEquals("NativeCRSs value is incorrect", "EPSG:4326", - supportedCRSs.getRequestResponseCRSs().get(0)); + assertNotNull(supportedCRSs, "SupportedCRSs is null"); + assertNotNull(supportedCRSs.getRequestResponseCRSs(), "SupportedCRSs requestResponses is null"); + assertEquals(1, supportedCRSs.getRequestResponseCRSs().size(), "SupportedCRSs requestResponse count is incorrect"); + assertEquals("EPSG:4326", supportedCRSs.getRequestResponseCRSs().get(0), "RequestResponse value is incorrect"); + assertNotNull(supportedCRSs.getNativeCRSs(), "SupportedCRSs nativeCRSs is null"); + assertEquals(1, supportedCRSs.getRequestResponseCRSs().size(), "SupportedCRSs nativeCRSs count is incorrect"); + assertEquals("EPSG:4326", supportedCRSs.getRequestResponseCRSs().get(0), "NativeCRSs value is incorrect"); WCS100SupportedInterpolations supportedInterpolations = coverage.getSupportedInterpolations(); - assertNotNull("SupportedInterpolations is null", supportedInterpolations); - assertEquals("SupportedInterpolations count is incorrect", 3, supportedInterpolations.getStrings().size()); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("nearest neighbor")); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("bilinear")); - assertTrue("Missing interpolation", supportedInterpolations.getStrings().contains("bicubic")); - assertEquals("Supported Interpolations default is incorrect", "nearest neighbor", - supportedInterpolations.getDefault()); + assertNotNull(supportedInterpolations, "SupportedInterpolations is null"); + assertEquals(3, supportedInterpolations.getStrings().size(), "SupportedInterpolations count is incorrect"); + assertTrue(supportedInterpolations.getStrings().contains("nearest neighbor"), "Missing interpolation"); + assertTrue(supportedInterpolations.getStrings().contains("bilinear"), "Missing interpolation"); + assertTrue(supportedInterpolations.getStrings().contains("bicubic"), "Missing interpolation"); + assertEquals("nearest neighbor", supportedInterpolations.getDefault(), "Supported Interpolations default is incorrect"); } } diff --git a/test/gov/nasa/worldwind/ogc/wcs/WCSElevationModelCreationTest.java b/test/gov/nasa/worldwind/ogc/wcs/WCSElevationModelCreationTest.java index 5533b7e25b..62c423f2ae 100644 --- a/test/gov/nasa/worldwind/ogc/wcs/WCSElevationModelCreationTest.java +++ b/test/gov/nasa/worldwind/ogc/wcs/WCSElevationModelCreationTest.java @@ -32,16 +32,12 @@ import gov.nasa.worldwind.geom.Sector; import gov.nasa.worldwind.ogc.wcs.wcs100.*; import gov.nasa.worldwind.terrain.WCSElevationModel; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import javax.xml.stream.XMLStreamException; import java.io.File; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class WCSElevationModelCreationTest { @Test @@ -51,20 +47,16 @@ public void test001() new WCS100Capabilities("testData/WCS/WCSCapabilities003.xml"), new WCS100DescribeCoverage("testData/WCS/WCSDescribeCoverage001.xml")); - assertEquals("Incorrect number of levels", 5, elevationModel.getLevels().getNumLevels()); + assertEquals(5, elevationModel.getLevels().getNumLevels(), "Incorrect number of levels"); double bestResolution = elevationModel.getBestResolution(Sector.FULL_SPHERE) * 180.0 / Math.PI; - assertTrue("Incorrect best resolution", bestResolution > 0.0083 && bestResolution < 0.0084); - - assertEquals("Min elevation incorrect", -11000.0, elevationModel.getMinElevation(), 0.0); - assertEquals("Max elevation incorrect", 8850.0, elevationModel.getMaxElevation(), 0.0); - - assertEquals("Incorrect dataset name", "WW:NASA_SRTM30_900m_Tiled", - elevationModel.getLevels().getFirstLevel().getDataset()); - assertEquals("Incorrect format suffix", ".tif", - elevationModel.getLevels().getFirstLevel().getFormatSuffix()); - assertEquals("Incorrect cache name", - "worldwind26.arc.nasa.gov" + File.separator + "_wms2" + File.separator + "WW_NASA_SRTM30_900m_Tiled", - elevationModel.getLevels().getFirstLevel().getCacheName()); + assertTrue(bestResolution > 0.0083 && bestResolution < 0.0084, "Incorrect best resolution"); + + assertEquals(-11000.0, elevationModel.getMinElevation(), 0.0, "Min elevation incorrect"); + assertEquals(8850.0, elevationModel.getMaxElevation(), 0.0, "Max elevation incorrect"); + + assertEquals("WW:NASA_SRTM30_900m_Tiled", elevationModel.getLevels().getFirstLevel().getDataset(), "Incorrect dataset name"); + assertEquals(".tif", elevationModel.getLevels().getFirstLevel().getFormatSuffix(), "Incorrect format suffix"); + assertEquals("worldwind26.arc.nasa.gov" + File.separator + "_wms2" + File.separator + "WW_NASA_SRTM30_900m_Tiled", elevationModel.getLevels().getFirstLevel().getCacheName(), "Incorrect cache name"); } @Test @@ -78,29 +70,19 @@ public void testRestoreState() WCSElevationModel newElevationModel = new WCSElevationModel(restorableState); - assertEquals("Incorrect number of levels", - origElevationModel.getLevels().getNumLevels(), - newElevationModel.getLevels().getNumLevels()); + assertEquals(origElevationModel.getLevels().getNumLevels(), newElevationModel.getLevels().getNumLevels(), "Incorrect number of levels"); double epsilon = 0.0001; double origBestResolution = origElevationModel.getBestResolution(Sector.FULL_SPHERE); double newBestResolution = newElevationModel.getBestResolution(Sector.FULL_SPHERE); - assertTrue("Incorrect best resolution", Math.abs(origBestResolution - newBestResolution) < epsilon); - - assertEquals("Min elevation incorrect", origElevationModel.getMinElevation(), - newElevationModel.getMinElevation(), 0.0); - assertEquals("Max elevation incorrect", origElevationModel.getMaxElevation(), - newElevationModel.getMaxElevation(), 0.0); - - assertEquals("Incorrect dataset name", - origElevationModel.getLevels().getFirstLevel().getDataset(), - newElevationModel.getLevels().getFirstLevel().getDataset()); - assertEquals("Incorrect format suffix", - origElevationModel.getLevels().getFirstLevel().getFormatSuffix(), - newElevationModel.getLevels().getFirstLevel().getFormatSuffix()); - assertEquals("Incorrect cache name", - origElevationModel.getLevels().getFirstLevel().getCacheName(), - newElevationModel.getLevels().getFirstLevel().getCacheName()); + assertTrue(Math.abs(origBestResolution - newBestResolution) < epsilon, "Incorrect best resolution"); + + assertEquals(origElevationModel.getMinElevation(), newElevationModel.getMinElevation(), 0.0, "Min elevation incorrect"); + assertEquals(origElevationModel.getMaxElevation(), newElevationModel.getMaxElevation(), 0.0, "Max elevation incorrect"); + + assertEquals(origElevationModel.getLevels().getFirstLevel().getDataset(), newElevationModel.getLevels().getFirstLevel().getDataset(), "Incorrect dataset name"); + assertEquals(origElevationModel.getLevels().getFirstLevel().getFormatSuffix(), newElevationModel.getLevels().getFirstLevel().getFormatSuffix(), "Incorrect format suffix"); + assertEquals(origElevationModel.getLevels().getFirstLevel().getCacheName(), newElevationModel.getLevels().getFirstLevel().getCacheName(), "Incorrect cache name"); } private WCSElevationModel createWCSElevationModel(WCS100Capabilities caps, WCS100DescribeCoverage coverage) diff --git a/test/gov/nasa/worldwind/render/AnnotationAttributesTest.java b/test/gov/nasa/worldwind/render/AnnotationAttributesTest.java index 456962a95e..d033945f2f 100644 --- a/test/gov/nasa/worldwind/render/AnnotationAttributesTest.java +++ b/test/gov/nasa/worldwind/render/AnnotationAttributesTest.java @@ -28,13 +28,9 @@ package gov.nasa.worldwind.render; import gov.nasa.worldwind.avlist.AVKey; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class AnnotationAttributesTest { ////////////////////////////////////////////////////////// @@ -278,38 +274,38 @@ private static void assignPartialExampleValues(AnnotationAttributes attrib) private static void assertAnnotationAttributesEquals(AnnotationAttributes expected, AnnotationAttributes actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("frameShape", expected.getFrameShape(), actual.getFrameShape()); - assertEquals("highlighted", expected.isHighlighted(), actual.isHighlighted()); - assertEquals("highlightScale", expected.getHighlightScale(), actual.getHighlightScale(), 0.0); - assertEquals("size", expected.getSize(), actual.getSize()); - assertEquals("scale", expected.getScale(), actual.getScale(), 0.0); - assertEquals("opacity", expected.getOpacity(), actual.getOpacity(), 0.0); - assertEquals("leader", expected.getLeader(), actual.getLeader()); - assertEquals("leaderGapWidth", expected.getLeaderGapWidth(), actual.getLeaderGapWidth()); - assertEquals("cornerRadius", expected.getCornerRadius(), actual.getCornerRadius()); - assertEquals("adjustWidthToText", expected.getAdjustWidthToText(), actual.getAdjustWidthToText()); - assertEquals("drawOffset", expected.getDrawOffset(), actual.getDrawOffset()); - assertEquals("insets", expected.getInsets(), actual.getInsets()); - assertEquals("borderWidth", expected.getBorderWidth(), actual.getBorderWidth(), 0.0); - assertEquals("borderStippleFactor", expected.getBorderStippleFactor(), actual.getBorderStippleFactor()); - assertEquals("borderStipplePattern", expected.getBorderStipplePattern(), actual.getBorderStipplePattern()); - assertEquals("antiAliasHint", expected.getAntiAliasHint(), actual.getAntiAliasHint()); - assertEquals("visible", expected.isVisible(), actual.isVisible()); - assertEquals("font", expected.getFont(), actual.getFont()); - assertEquals("textAlign", expected.getTextAlign(), actual.getTextAlign()); - assertEquals("textColor", expected.getTextColor(), actual.getTextColor()); - assertEquals("backgroundColor", expected.getBackgroundColor(), actual.getBackgroundColor()); - assertEquals("borderColor", expected.getBorderColor(), actual.getBorderColor()); - assertEquals("imageSource", expected.getImageSource(), actual.getImageSource()); - assertEquals("imageScale", expected.getImageScale(), actual.getImageScale(), 0.0); - assertEquals("imageOffset", expected.getImageOffset(), actual.getImageOffset()); - assertEquals("imageOpacity", expected.getImageOpacity(), actual.getImageOpacity(), 0.0); - assertEquals("imageRepeat", expected.getImageRepeat(), actual.getImageRepeat()); - assertEquals("distanceMinScale", expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0); - assertEquals("distanceMaxScale", expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0); - assertEquals("distanceMinOpacity", expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0); - assertEquals("effect", expected.getEffect(), actual.getEffect()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getFrameShape(), actual.getFrameShape(), "frameShape"); + assertEquals(expected.isHighlighted(), actual.isHighlighted(), "highlighted"); + assertEquals(expected.getHighlightScale(), actual.getHighlightScale(), 0.0, "highlightScale"); + assertEquals(expected.getSize(), actual.getSize(), "size"); + assertEquals(expected.getScale(), actual.getScale(), 0.0, "scale"); + assertEquals(expected.getOpacity(), actual.getOpacity(), 0.0, "opacity"); + assertEquals(expected.getLeader(), actual.getLeader(), "leader"); + assertEquals(expected.getLeaderGapWidth(), actual.getLeaderGapWidth(), "leaderGapWidth"); + assertEquals(expected.getCornerRadius(), actual.getCornerRadius(), "cornerRadius"); + assertEquals(expected.getAdjustWidthToText(), actual.getAdjustWidthToText(), "adjustWidthToText"); + assertEquals(expected.getDrawOffset(), actual.getDrawOffset(), "drawOffset"); + assertEquals(expected.getInsets(), actual.getInsets(), "insets"); + assertEquals(expected.getBorderWidth(), actual.getBorderWidth(), 0.0, "borderWidth"); + assertEquals(expected.getBorderStippleFactor(), actual.getBorderStippleFactor(), "borderStippleFactor"); + assertEquals(expected.getBorderStipplePattern(), actual.getBorderStipplePattern(), "borderStipplePattern"); + assertEquals(expected.getAntiAliasHint(), actual.getAntiAliasHint(), "antiAliasHint"); + assertEquals(expected.isVisible(), actual.isVisible(), "visible"); + assertEquals(expected.getFont(), actual.getFont(), "font"); + assertEquals(expected.getTextAlign(), actual.getTextAlign(), "textAlign"); + assertEquals(expected.getTextColor(), actual.getTextColor(), "textColor"); + assertEquals(expected.getBackgroundColor(), actual.getBackgroundColor(), "backgroundColor"); + assertEquals(expected.getBorderColor(), actual.getBorderColor(), "borderColor"); + assertEquals(expected.getImageSource(), actual.getImageSource(), "imageSource"); + assertEquals(expected.getImageScale(), actual.getImageScale(), 0.0, "imageScale"); + assertEquals(expected.getImageOffset(), actual.getImageOffset(), "imageOffset"); + assertEquals(expected.getImageOpacity(), actual.getImageOpacity(), 0.0, "imageOpacity"); + assertEquals(expected.getImageRepeat(), actual.getImageRepeat(), "imageRepeat"); + assertEquals(expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0, "distanceMinScale"); + assertEquals(expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0, "distanceMaxScale"); + assertEquals(expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0, "distanceMinOpacity"); + assertEquals(expected.getEffect(), actual.getEffect(), "effect"); } } diff --git a/test/gov/nasa/worldwind/render/GlobeAnnotationTest.java b/test/gov/nasa/worldwind/render/GlobeAnnotationTest.java index d5fda4507d..e6677bb6b8 100644 --- a/test/gov/nasa/worldwind/render/GlobeAnnotationTest.java +++ b/test/gov/nasa/worldwind/render/GlobeAnnotationTest.java @@ -29,13 +29,9 @@ import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.geom.Position; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class GlobeAnnotationTest { ////////////////////////////////////////////////////////// @@ -144,7 +140,7 @@ public void testRestore_AnnotationSharing() assignNullValues(annotation1); annotation1.restoreState(stateInXml); - assertSame("Attributes are shared", annotation1.getAttributes(), annotation2.getAttributes()); + assertSame(annotation1.getAttributes(), annotation2.getAttributes(), "Attributes are shared"); AnnotationAttributes expected = new AnnotationAttributes(); assignExampleValues(expected); assertAnnotationAttributesEquals(expected, annotation2.getAttributes()); @@ -252,66 +248,64 @@ private static void assignNullValues(AnnotationAttributes attrib) private static void assertAnnotationEquals(Annotation expected, Annotation actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("text", expected.getText(), actual.getText()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getText(), actual.getText(), "text"); assertAnnotationAttributesEquals(expected.getAttributes(), actual.getAttributes()); } private static void assertGlobeAnnotationEquals(GlobeAnnotation expected, GlobeAnnotation actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("text", expected.getText(), actual.getText()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getText(), actual.getText(), "text"); if (expected.getPosition() != null && actual.getPosition() != null) { - assertEquals("position.latitude", expected.getPosition().getLatitude(), actual.getPosition().getLatitude()); - assertEquals("position.longitude", expected.getPosition().getLongitude(), - actual.getPosition().getLongitude()); - assertEquals("position.elevation", expected.getPosition().getElevation(), - actual.getPosition().getElevation(), 0.0); + assertEquals(expected.getPosition().getLatitude(), actual.getPosition().getLatitude(), "position.latitude"); + assertEquals(expected.getPosition().getLongitude(), actual.getPosition().getLongitude(), "position.longitude"); + assertEquals(expected.getPosition().getElevation(), actual.getPosition().getElevation(), 0.0, "position.elevation"); } else { - assertNull("Expected position is not null", expected.getPosition()); - assertNull("Actual position is not null", actual.getPosition()); + assertNull(expected.getPosition(), "Expected position is not null"); + assertNull(actual.getPosition(), "Actual position is not null"); } assertAnnotationAttributesEquals(expected.getAttributes(), actual.getAttributes()); } private static void assertAnnotationAttributesEquals(AnnotationAttributes expected, AnnotationAttributes actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("frameShape", expected.getFrameShape(), actual.getFrameShape()); - assertEquals("highlighted", expected.isHighlighted(), actual.isHighlighted()); - assertEquals("highlightScale", expected.getHighlightScale(), actual.getHighlightScale(), 0.0); - assertEquals("size", expected.getSize(), actual.getSize()); - assertEquals("scale", expected.getScale(), actual.getScale(), 0.0); - assertEquals("opacity", expected.getOpacity(), actual.getOpacity(), 0.0); - assertEquals("leader", expected.getLeader(), actual.getLeader()); - assertEquals("cornerRadius", expected.getCornerRadius(), actual.getCornerRadius()); - assertEquals("adjustWidthToText", expected.getAdjustWidthToText(), actual.getAdjustWidthToText()); - assertEquals("drawOffset", expected.getDrawOffset(), actual.getDrawOffset()); - assertEquals("insets", expected.getInsets(), actual.getInsets()); - assertEquals("borderWidth", expected.getBorderWidth(), actual.getBorderWidth(), 0.0); - assertEquals("borderStippleFactor", expected.getBorderStippleFactor(), actual.getBorderStippleFactor()); - assertEquals("borderStipplePattern", expected.getBorderStipplePattern(), actual.getBorderStipplePattern()); - assertEquals("antiAliasHint", expected.getAntiAliasHint(), actual.getAntiAliasHint()); - assertEquals("visible", expected.isVisible(), actual.isVisible()); - assertEquals("font", expected.getFont(), actual.getFont()); - assertEquals("textAlign", expected.getTextAlign(), actual.getTextAlign()); - assertEquals("textColor", expected.getTextColor(), actual.getTextColor()); - assertEquals("backgroundColor", expected.getBackgroundColor(), actual.getBackgroundColor()); - assertEquals("borderColor", expected.getBorderColor(), actual.getBorderColor()); - assertEquals("imageSource", expected.getImageSource(), actual.getImageSource()); - assertEquals("imageScale", expected.getImageScale(), actual.getImageScale(), 0.0); - assertEquals("imageOffset", expected.getImageOffset(), actual.getImageOffset()); - assertEquals("imageOpacity", expected.getImageOpacity(), actual.getImageOpacity(), 0.0); - assertEquals("imageRepeat", expected.getImageRepeat(), actual.getImageRepeat()); - assertEquals("distanceMinScale", expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0); - assertEquals("distanceMaxScale", expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0); - assertEquals("distanceMinOpacity", expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0); - assertEquals("effect", expected.getEffect(), actual.getEffect()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getFrameShape(), actual.getFrameShape(), "frameShape"); + assertEquals(expected.isHighlighted(), actual.isHighlighted(), "highlighted"); + assertEquals(expected.getHighlightScale(), actual.getHighlightScale(), 0.0, "highlightScale"); + assertEquals(expected.getSize(), actual.getSize(), "size"); + assertEquals(expected.getScale(), actual.getScale(), 0.0, "scale"); + assertEquals(expected.getOpacity(), actual.getOpacity(), 0.0, "opacity"); + assertEquals(expected.getLeader(), actual.getLeader(), "leader"); + assertEquals(expected.getCornerRadius(), actual.getCornerRadius(), "cornerRadius"); + assertEquals(expected.getAdjustWidthToText(), actual.getAdjustWidthToText(), "adjustWidthToText"); + assertEquals(expected.getDrawOffset(), actual.getDrawOffset(), "drawOffset"); + assertEquals(expected.getInsets(), actual.getInsets(), "insets"); + assertEquals(expected.getBorderWidth(), actual.getBorderWidth(), 0.0, "borderWidth"); + assertEquals(expected.getBorderStippleFactor(), actual.getBorderStippleFactor(), "borderStippleFactor"); + assertEquals(expected.getBorderStipplePattern(), actual.getBorderStipplePattern(), "borderStipplePattern"); + assertEquals(expected.getAntiAliasHint(), actual.getAntiAliasHint(), "antiAliasHint"); + assertEquals(expected.isVisible(), actual.isVisible(), "visible"); + assertEquals(expected.getFont(), actual.getFont(), "font"); + assertEquals(expected.getTextAlign(), actual.getTextAlign(), "textAlign"); + assertEquals(expected.getTextColor(), actual.getTextColor(), "textColor"); + assertEquals(expected.getBackgroundColor(), actual.getBackgroundColor(), "backgroundColor"); + assertEquals(expected.getBorderColor(), actual.getBorderColor(), "borderColor"); + assertEquals(expected.getImageSource(), actual.getImageSource(), "imageSource"); + assertEquals(expected.getImageScale(), actual.getImageScale(), 0.0, "imageScale"); + assertEquals(expected.getImageOffset(), actual.getImageOffset(), "imageOffset"); + assertEquals(expected.getImageOpacity(), actual.getImageOpacity(), 0.0, "imageOpacity"); + assertEquals(expected.getImageRepeat(), actual.getImageRepeat(), "imageRepeat"); + assertEquals(expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0, "distanceMinScale"); + assertEquals(expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0, "distanceMaxScale"); + assertEquals(expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0, "distanceMinOpacity"); + assertEquals(expected.getEffect(), actual.getEffect(), "effect"); } } \ No newline at end of file diff --git a/test/gov/nasa/worldwind/render/PedestalTest.java b/test/gov/nasa/worldwind/render/PedestalTest.java index 5f23146206..154e3735ae 100644 --- a/test/gov/nasa/worldwind/render/PedestalTest.java +++ b/test/gov/nasa/worldwind/render/PedestalTest.java @@ -28,15 +28,11 @@ package gov.nasa.worldwind.render; import gov.nasa.worldwind.geom.Position; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.awt.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class PedestalTest { ////////////////////////////////////////////////////////// @@ -182,33 +178,31 @@ private static void assignNullValues(Pedestal pedestal) private static void assertPedestalEquals(Pedestal expected, Pedestal actual) { // WWIcon equality - assertNotNull("Expected is null", expected); - assertNotNull("Actual is null", actual); - assertEquals("imageSource", expected.getImageSource(), actual.getImageSource()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Actual is null"); + assertEquals(expected.getImageSource(), actual.getImageSource(), "imageSource"); if (expected.getPosition() != null && actual.getPosition() != null) { - assertEquals("position.latitude", expected.getPosition().getLatitude(), actual.getPosition().getLatitude()); - assertEquals("position.longitude", expected.getPosition().getLongitude(), - actual.getPosition().getLongitude()); - assertEquals("position.elevation", expected.getPosition().getElevation(), - actual.getPosition().getElevation(), 0.0); + assertEquals(expected.getPosition().getLatitude(), actual.getPosition().getLatitude(), "position.latitude"); + assertEquals(expected.getPosition().getLongitude(), actual.getPosition().getLongitude(), "position.longitude"); + assertEquals(expected.getPosition().getElevation(), actual.getPosition().getElevation(), 0.0, "position.elevation"); } else { - assertNull("Expected position is not null", expected.getPosition()); - assertNull("Actual position is not null", actual.getPosition()); + assertNull(expected.getPosition(), "Expected position is not null"); + assertNull(actual.getPosition(), "Actual position is not null"); } - assertEquals("highlighted", expected.isHighlighted(), actual.isHighlighted()); - assertEquals("size", expected.getSize(), actual.getSize()); - assertEquals("visible", expected.isVisible(), actual.isVisible()); - assertEquals("highlightScale", expected.getHighlightScale(), actual.getHighlightScale(), 0.0); - assertEquals("toolTipText", expected.getToolTipText(), actual.getToolTipText()); - assertEquals("toolTipFont", expected.getToolTipFont(), actual.getToolTipFont()); - assertEquals("showToolTip", expected.isShowToolTip(), actual.isShowToolTip()); - assertEquals("toolTipTextColor", expected.getToolTipTextColor(), actual.getToolTipTextColor()); - assertEquals("alwaysOnTop", expected.isAlwaysOnTop(), actual.isAlwaysOnTop()); + assertEquals(expected.isHighlighted(), actual.isHighlighted(), "highlighted"); + assertEquals(expected.getSize(), actual.getSize(), "size"); + assertEquals(expected.isVisible(), actual.isVisible(), "visible"); + assertEquals(expected.getHighlightScale(), actual.getHighlightScale(), 0.0, "highlightScale"); + assertEquals(expected.getToolTipText(), actual.getToolTipText(), "toolTipText"); + assertEquals(expected.getToolTipFont(), actual.getToolTipFont(), "toolTipFont"); + assertEquals(expected.isShowToolTip(), actual.isShowToolTip(), "showToolTip"); + assertEquals(expected.getToolTipTextColor(), actual.getToolTipTextColor(), "toolTipTextColor"); + assertEquals(expected.isAlwaysOnTop(), actual.isAlwaysOnTop(), "alwaysOnTop"); // Pedestal equality - assertEquals("spacingPixels", expected.getSpacingPixels(), actual.getSpacingPixels(), 0.0); - assertEquals("scale", expected.getScale(), actual.getScale(), 0.0); + assertEquals(expected.getSpacingPixels(), actual.getSpacingPixels(), 0.0, "spacingPixels"); + assertEquals(expected.getScale(), actual.getScale(), 0.0, "scale"); } } diff --git a/test/gov/nasa/worldwind/render/PolygonTest.java b/test/gov/nasa/worldwind/render/PolygonTest.java index 36fc3618c4..bf5641f324 100644 --- a/test/gov/nasa/worldwind/render/PolygonTest.java +++ b/test/gov/nasa/worldwind/render/PolygonTest.java @@ -31,15 +31,13 @@ import gov.nasa.worldwind.WorldWind; import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.globes.*; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.util.*; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class PolygonTest { private Globe globe; @@ -47,7 +45,7 @@ public class PolygonTest private List positions; private Sector sector; - @Before + @BeforeEach public void setUp() { this.globe = new Earth(); @@ -60,7 +58,7 @@ public void setUp() this.sector = Sector.boundingSector(this.positions); } - @After + @AfterEach public void tearDown() { this.globe = null; diff --git a/test/gov/nasa/worldwind/render/PolylineTest.java b/test/gov/nasa/worldwind/render/PolylineTest.java index e312d9b431..78a4b1de9c 100644 --- a/test/gov/nasa/worldwind/render/PolylineTest.java +++ b/test/gov/nasa/worldwind/render/PolylineTest.java @@ -28,17 +28,14 @@ package gov.nasa.worldwind.render; import gov.nasa.worldwind.geom.Position; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.awt.*; import java.util.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; @SuppressWarnings("deprecation") -@RunWith(JUnit4.class) public class PolylineTest { ////////////////////////////////////////////////////////// @@ -181,34 +178,34 @@ private static void assignNullValues(Polyline polyline) private static void assertPolylineEquals(Polyline expected, Polyline actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Actual is null", actual); - - assertEquals("color", expected.getColor(), actual.getColor()); - assertEquals("highlightColor", expected.getColor(), actual.getColor()); - assertEquals("antiAliasHint", expected.getAntiAliasHint(), actual.getAntiAliasHint()); - assertEquals("filled", expected.isFilled(), actual.isFilled()); - assertEquals("closed", expected.isClosed(), actual.isClosed()); - assertEquals("highlighted", expected.isFilled(), actual.isFilled()); - assertEquals("pathType", expected.getPathType(), actual.getPathType()); - assertEquals("followTerrain", expected.isFollowTerrain(), actual.isFollowTerrain()); - assertEquals("offset", expected.getOffset(), actual.getOffset(), 0.0); - assertEquals("terrainConformance", expected.getTerrainConformance(), actual.getTerrainConformance(), 0.0); - assertEquals("lineWidth", expected.getLineWidth(), actual.getLineWidth(), 0.0); - assertEquals("stipplePattern", expected.getStipplePattern(), actual.getStipplePattern()); - assertEquals("stippleFactor", expected.getStippleFactor(), actual.getStippleFactor()); - assertEquals("numSubsegments", expected.getNumSubsegments(), actual.getNumSubsegments()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Actual is null"); + + assertEquals(expected.getColor(), actual.getColor(), "color"); + assertEquals(expected.getColor(), actual.getColor(), "highlightColor"); + assertEquals(expected.getAntiAliasHint(), actual.getAntiAliasHint(), "antiAliasHint"); + assertEquals(expected.isFilled(), actual.isFilled(), "filled"); + assertEquals(expected.isClosed(), actual.isClosed(), "closed"); + assertEquals(expected.isFilled(), actual.isFilled(), "highlighted"); + assertEquals(expected.getPathType(), actual.getPathType(), "pathType"); + assertEquals(expected.isFollowTerrain(), actual.isFollowTerrain(), "followTerrain"); + assertEquals(expected.getOffset(), actual.getOffset(), 0.0, "offset"); + assertEquals(expected.getTerrainConformance(), actual.getTerrainConformance(), 0.0, "terrainConformance"); + assertEquals(expected.getLineWidth(), actual.getLineWidth(), 0.0, "lineWidth"); + assertEquals(expected.getStipplePattern(), actual.getStipplePattern(), "stipplePattern"); + assertEquals(expected.getStippleFactor(), actual.getStippleFactor(), "stippleFactor"); + assertEquals(expected.getNumSubsegments(), actual.getNumSubsegments(), "numSubsegments"); // Position does not override equals(), so we must compare the contents of "positions" ourselves. Iterator expectedPositions = expected.getPositions().iterator(); Iterator actualPositions = actual.getPositions().iterator(); while (expectedPositions.hasNext() && actualPositions.hasNext()) { Position expectedPos = expectedPositions.next(), actualPos = actualPositions.next(); - assertEquals("positions.i.latitude", expectedPos.getLatitude(), actualPos.getLatitude()); - assertEquals("positions.i.longitude", expectedPos.getLongitude(), actualPos.getLongitude()); - assertEquals("positions.i.elevation", expectedPos.getElevation(), actualPos.getElevation(), 0.0); + assertEquals(expectedPos.getLatitude(), actualPos.getLatitude(), "positions.i.latitude"); + assertEquals(expectedPos.getLongitude(), actualPos.getLongitude(), "positions.i.longitude"); + assertEquals(expectedPos.getElevation(), actualPos.getElevation(), 0.0, "positions.i.elevation"); } // If either iterator has more elements, then their lengths are different. - assertFalse("positions.length", expectedPositions.hasNext() || actualPositions.hasNext()); + assertFalse(expectedPositions.hasNext() || actualPositions.hasNext(), "positions.length"); } } diff --git a/test/gov/nasa/worldwind/render/ScreenAnnotationTest.java b/test/gov/nasa/worldwind/render/ScreenAnnotationTest.java index 9d415ec34d..14d53c2f99 100644 --- a/test/gov/nasa/worldwind/render/ScreenAnnotationTest.java +++ b/test/gov/nasa/worldwind/render/ScreenAnnotationTest.java @@ -29,13 +29,9 @@ import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.geom.Position; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class ScreenAnnotationTest { ////////////////////////////////////////////////////////// @@ -144,7 +140,7 @@ public void testRestore_AnnotationSharing() assignNullValues(annotation1); annotation1.restoreState(stateInXml); - assertSame("Attributes are shared", annotation1.getAttributes(), annotation2.getAttributes()); + assertSame(annotation1.getAttributes(), annotation2.getAttributes(), "Attributes are shared"); AnnotationAttributes expected = new AnnotationAttributes(); assignExampleValues(expected); assertAnnotationAttributesEquals(expected, annotation2.getAttributes()); @@ -254,54 +250,54 @@ private static void assignNullValues(AnnotationAttributes attrib) private static void assertAnnotationEquals(Annotation expected, Annotation actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("text", expected.getText(), actual.getText()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getText(), actual.getText(), "text"); assertAnnotationAttributesEquals(expected.getAttributes(), actual.getAttributes()); } private static void assertScreenAnnotationEquals(ScreenAnnotation expected, ScreenAnnotation actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("text", expected.getText(), actual.getText()); - assertEquals("screenPoint", expected.getScreenPoint(), actual.getScreenPoint()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getText(), actual.getText(), "text"); + assertEquals(expected.getScreenPoint(), actual.getScreenPoint(), "screenPoint"); assertAnnotationAttributesEquals(expected.getAttributes(), actual.getAttributes()); } private static void assertAnnotationAttributesEquals(AnnotationAttributes expected, AnnotationAttributes actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Acutal is null", actual); - assertEquals("frameShape", expected.getFrameShape(), actual.getFrameShape()); - assertEquals("highlighted", expected.isHighlighted(), actual.isHighlighted()); - assertEquals("highlightScale", expected.getHighlightScale(), actual.getHighlightScale(), 0.0); - assertEquals("size", expected.getSize(), actual.getSize()); - assertEquals("scale", expected.getScale(), actual.getScale(), 0.0); - assertEquals("opacity", expected.getOpacity(), actual.getOpacity(), 0.0); - assertEquals("leader", expected.getLeader(), actual.getLeader()); - assertEquals("cornerRadius", expected.getCornerRadius(), actual.getCornerRadius()); - assertEquals("adjustWidthToText", expected.getAdjustWidthToText(), actual.getAdjustWidthToText()); - assertEquals("drawOffset", expected.getDrawOffset(), actual.getDrawOffset()); - assertEquals("insets", expected.getInsets(), actual.getInsets()); - assertEquals("borderWidth", expected.getBorderWidth(), actual.getBorderWidth(), 0.0); - assertEquals("borderStippleFactor", expected.getBorderStippleFactor(), actual.getBorderStippleFactor()); - assertEquals("borderStipplePattern", expected.getBorderStipplePattern(), actual.getBorderStipplePattern()); - assertEquals("antiAliasHint", expected.getAntiAliasHint(), actual.getAntiAliasHint()); - assertEquals("visible", expected.isVisible(), actual.isVisible()); - assertEquals("font", expected.getFont(), actual.getFont()); - assertEquals("textAlign", expected.getTextAlign(), actual.getTextAlign()); - assertEquals("textColor", expected.getTextColor(), actual.getTextColor()); - assertEquals("backgroundColor", expected.getBackgroundColor(), actual.getBackgroundColor()); - assertEquals("borderColor", expected.getBorderColor(), actual.getBorderColor()); - assertEquals("imageSource", expected.getImageSource(), actual.getImageSource()); - assertEquals("imageScale", expected.getImageScale(), actual.getImageScale(), 0.0); - assertEquals("imageOffset", expected.getImageOffset(), actual.getImageOffset()); - assertEquals("imageOpacity", expected.getImageOpacity(), actual.getImageOpacity(), 0.0); - assertEquals("imageRepeat", expected.getImageRepeat(), actual.getImageRepeat()); - assertEquals("distanceMinScale", expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0); - assertEquals("distanceMaxScale", expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0); - assertEquals("distanceMinOpacity", expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0); - assertEquals("effect", expected.getEffect(), actual.getEffect()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Acutal is null"); + assertEquals(expected.getFrameShape(), actual.getFrameShape(), "frameShape"); + assertEquals(expected.isHighlighted(), actual.isHighlighted(), "highlighted"); + assertEquals(expected.getHighlightScale(), actual.getHighlightScale(), 0.0, "highlightScale"); + assertEquals(expected.getSize(), actual.getSize(), "size"); + assertEquals(expected.getScale(), actual.getScale(), 0.0, "scale"); + assertEquals(expected.getOpacity(), actual.getOpacity(), 0.0, "opacity"); + assertEquals(expected.getLeader(), actual.getLeader(), "leader"); + assertEquals(expected.getCornerRadius(), actual.getCornerRadius(), "cornerRadius"); + assertEquals(expected.getAdjustWidthToText(), actual.getAdjustWidthToText(), "adjustWidthToText"); + assertEquals(expected.getDrawOffset(), actual.getDrawOffset(), "drawOffset"); + assertEquals(expected.getInsets(), actual.getInsets(), "insets"); + assertEquals(expected.getBorderWidth(), actual.getBorderWidth(), 0.0, "borderWidth"); + assertEquals(expected.getBorderStippleFactor(), actual.getBorderStippleFactor(), "borderStippleFactor"); + assertEquals(expected.getBorderStipplePattern(), actual.getBorderStipplePattern(), "borderStipplePattern"); + assertEquals(expected.getAntiAliasHint(), actual.getAntiAliasHint(), "antiAliasHint"); + assertEquals(expected.isVisible(), actual.isVisible(), "visible"); + assertEquals(expected.getFont(), actual.getFont(), "font"); + assertEquals(expected.getTextAlign(), actual.getTextAlign(), "textAlign"); + assertEquals(expected.getTextColor(), actual.getTextColor(), "textColor"); + assertEquals(expected.getBackgroundColor(), actual.getBackgroundColor(), "backgroundColor"); + assertEquals(expected.getBorderColor(), actual.getBorderColor(), "borderColor"); + assertEquals(expected.getImageSource(), actual.getImageSource(), "imageSource"); + assertEquals(expected.getImageScale(), actual.getImageScale(), 0.0, "imageScale"); + assertEquals(expected.getImageOffset(), actual.getImageOffset(), "imageOffset"); + assertEquals(expected.getImageOpacity(), actual.getImageOpacity(), 0.0, "imageOpacity"); + assertEquals(expected.getImageRepeat(), actual.getImageRepeat(), "imageRepeat"); + assertEquals(expected.getDistanceMinScale(), actual.getDistanceMinScale(), 0.0, "distanceMinScale"); + assertEquals(expected.getDistanceMaxScale(), actual.getDistanceMaxScale(), 0.0, "distanceMaxScale"); + assertEquals(expected.getDistanceMinOpacity(), actual.getDistanceMinOpacity(), 0.0, "distanceMinOpacity"); + assertEquals(expected.getEffect(), actual.getEffect(), "effect"); } } diff --git a/test/gov/nasa/worldwind/render/ShapeAttributesTest.java b/test/gov/nasa/worldwind/render/ShapeAttributesTest.java index ba7db75fff..4c45443427 100644 --- a/test/gov/nasa/worldwind/render/ShapeAttributesTest.java +++ b/test/gov/nasa/worldwind/render/ShapeAttributesTest.java @@ -2,25 +2,25 @@ * Copyright 2006-2009, 2017, 2020 United States Government, as represented by the * Administrator of the National Aeronautics and Space Administration. * All rights reserved. - * + * * The NASA World Wind Java (WWJ) platform is licensed under the Apache License, * Version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. - * + * * NASA World Wind Java (WWJ) also contains the following 3rd party Open Source * software: - * + * * Jackson Parser – Licensed under Apache 2.0 * GDAL – Licensed under MIT * JOGL – Licensed under Berkeley Software Distribution (BSD) * Gluegen – Licensed under Berkeley Software Distribution (BSD) - * + * * A complete listing of 3rd Party software notices and licenses included in * NASA World Wind Java (WWJ) can be found in the WorldWindJava-v2.2 3rd-party * notices and licenses PDF found in code directory. @@ -29,20 +29,22 @@ import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.util.RestorableSupport; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.awt.*; -import java.util.*; +import java.util.stream.Stream; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; -@RunWith(Parameterized.class) public class ShapeAttributesTest { - @Parameterized.Parameters - public static Collection data() + /** + * Provides pairs of (defaultAttributes, exampleAttributes) — one pair per test invocation. + */ + @SuppressWarnings("unused") + static Stream data() { BasicShapeAttributes defaultBasicAttrs = new BasicShapeAttributes(); BasicShapeAttributes exampleBasicAttrs = new BasicShapeAttributes(); @@ -91,72 +93,58 @@ public static Collection data() exampleBalloonAttrs.setImageOpacity(0.5); exampleBalloonAttrs.setImageRepeat(AVKey.REPEAT_NONE); - return Arrays.asList(new Object[][] { - {defaultBasicAttrs, exampleBasicAttrs}, - {defaultBalloonAttrs, exampleBalloonAttrs} - }); + return Stream.of( + Arguments.of(defaultBasicAttrs, exampleBasicAttrs), + Arguments.of(defaultBalloonAttrs, exampleBalloonAttrs) + ); } - private ShapeAttributes defaultAttributes; - private ShapeAttributes exampleAttributes; - - public ShapeAttributesTest(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) - { - this.defaultAttributes = defaultAttributes; - this.exampleAttributes = exampleAttributes; - } - - @Test - public void testBasicSaveRestore() + @ParameterizedTest + @MethodSource("data") + public void testBasicSaveRestore(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) { RestorableSupport rs = RestorableSupport.newRestorableSupport(); - ShapeAttributes expected = this.exampleAttributes.copy(); + ShapeAttributes expected = exampleAttributes.copy(); expected.getRestorableState(rs, null); - ShapeAttributes actual = this.defaultAttributes.copy(); + ShapeAttributes actual = defaultAttributes.copy(); actual.restoreState(rs, null); assertEquals(expected, actual); } - @Test - public void testRestoreSameInstance() + @ParameterizedTest + @MethodSource("data") + public void testRestoreSameInstance(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) { RestorableSupport rs = RestorableSupport.newRestorableSupport(); - ShapeAttributes expected = this.exampleAttributes.copy(); + ShapeAttributes expected = exampleAttributes.copy(); - ShapeAttributes actual = this.exampleAttributes.copy(); + ShapeAttributes actual = exampleAttributes.copy(); actual.getRestorableState(rs, null); - actual.copy(this.defaultAttributes.copy()); + actual.copy(defaultAttributes.copy()); actual.restoreState(rs, null); assertEquals(expected, actual); } - @Test - public void testRestoreNullDocument() + @ParameterizedTest + @MethodSource("data") + public void testRestoreNullDocument(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) { - try - { - ShapeAttributes attrs = this.defaultAttributes.copy(); - attrs.restoreState(null, null); - fail("Expected an IllegalArgumentException"); - } - catch (Exception e) - { - e.printStackTrace(); - } + assertThrows(IllegalArgumentException.class, () -> defaultAttributes.copy().restoreState(null, null)); } - @Test - public void testRestoreEmptyDocument() + @ParameterizedTest + @MethodSource("data") + public void testRestoreEmptyDocument(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) { - ShapeAttributes expected = this.exampleAttributes.copy(); + ShapeAttributes expected = exampleAttributes.copy(); // Restoring an empty state document should not change any attributes. - ShapeAttributes actual = this.exampleAttributes.copy(); + ShapeAttributes actual = exampleAttributes.copy(); String emptyStateInXml = "" + ""; @@ -166,13 +154,14 @@ public void testRestoreEmptyDocument() assertEquals(expected, actual); } - @Test - public void testRestoreOneAttribute() + @ParameterizedTest + @MethodSource("data") + public void testRestoreOneAttribute(ShapeAttributes defaultAttributes, ShapeAttributes exampleAttributes) { - ShapeAttributes expected = this.exampleAttributes.copy(); + ShapeAttributes expected = exampleAttributes.copy(); expected.setOutlineWidth(11); - ShapeAttributes actual = this.exampleAttributes.copy(); + ShapeAttributes actual = exampleAttributes.copy(); String partialStateInXml = "" + "" + diff --git a/test/gov/nasa/worldwind/render/SizeTest.java b/test/gov/nasa/worldwind/render/SizeTest.java index 58f6558470..4173a2adaf 100644 --- a/test/gov/nasa/worldwind/render/SizeTest.java +++ b/test/gov/nasa/worldwind/render/SizeTest.java @@ -30,15 +30,11 @@ import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.util.RestorableSupport; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.awt.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class SizeTest { @Test @@ -47,12 +43,12 @@ public void testSize() // Test with native width and fractional height Size size = new Size(Size.NATIVE_DIMENSION, 0, AVKey.PIXELS, Size.EXPLICIT_DIMENSION, 0.5, AVKey.FRACTION); Dimension dim = size.compute(70, 10, 100, 100); - assertTrue("Dimension should be 70 x 50", dim.equals(new Dimension(70, 50))); + assertTrue(dim.equals(new Dimension(70, 50)), "Dimension should be 70 x 50"); // Test with maintain aspect ratio size = new Size(Size.MAINTAIN_ASPECT_RATIO, 0, AVKey.PIXELS, Size.EXPLICIT_DIMENSION, 50, AVKey.PIXELS); dim = size.compute(20, 10, 100, 100); - assertTrue("Dimension should be 100 x 50", dim.equals(new Dimension(100, 50))); + assertTrue(dim.equals(new Dimension(100, 50)), "Dimension should be 100 x 50"); } @Test @@ -63,8 +59,8 @@ public void testZeroSizeContainer() Dimension dim = size.compute(100, 100, 0, 0); - assertTrue("Dimension != null", dim != null); - assertTrue("Dimension should be zero", dim.equals(new Dimension(0, 0))); + assertTrue(dim != null, "Dimension != null"); + assertTrue(dim.equals(new Dimension(0, 0)), "Dimension should be zero"); } @Test @@ -74,22 +70,22 @@ public void testZeroSizeRect() Size size = new Size(Size.EXPLICIT_DIMENSION, 0.5, AVKey.FRACTION, Size.EXPLICIT_DIMENSION, 0.5, AVKey.FRACTION); Dimension dim = size.compute(0, 0, 100, 100); - assertTrue("Dimension should be 50 x 50", dim.equals(new Dimension(50, 50))); + assertTrue(dim.equals(new Dimension(50, 50)), "Dimension should be 50 x 50"); // Test with pixel dimensions size = new Size(Size.EXPLICIT_DIMENSION, 50, AVKey.PIXELS, Size.EXPLICIT_DIMENSION, 50, AVKey.PIXELS); dim = size.compute(0, 0, 100, 100); - assertTrue("Dimension should be 50 x 50", dim.equals(new Dimension(50, 50))); + assertTrue(dim.equals(new Dimension(50, 50)), "Dimension should be 50 x 50"); // Test with maintain aspect radio size = new Size(Size.MAINTAIN_ASPECT_RATIO, 0, AVKey.PIXELS, Size.MAINTAIN_ASPECT_RATIO, 0, AVKey.PIXELS); dim = size.compute(0, 0, 100, 100); - assertTrue("Dimension should be 0 x 0", dim.equals(new Dimension(0, 0))); + assertTrue(dim.equals(new Dimension(0, 0)), "Dimension should be 0 x 0"); // Test with native dimension size = new Size(Size.NATIVE_DIMENSION, 0, AVKey.PIXELS, Size.NATIVE_DIMENSION, 0, AVKey.PIXELS); dim = size.compute(0, 0, 100, 100); - assertTrue("Dimension should be 0 x 0", dim.equals(new Dimension(0, 0))); + assertTrue(dim.equals(new Dimension(0, 0)), "Dimension should be 0 x 0"); } @Test diff --git a/test/gov/nasa/worldwind/render/SurfaceShapeTest.java b/test/gov/nasa/worldwind/render/SurfaceShapeTest.java index a23517b45a..64b3a74f01 100644 --- a/test/gov/nasa/worldwind/render/SurfaceShapeTest.java +++ b/test/gov/nasa/worldwind/render/SurfaceShapeTest.java @@ -30,16 +30,13 @@ import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.geom.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.util.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; @SuppressWarnings("deprecation") -@RunWith(JUnit4.class) public class SurfaceShapeTest { private static final ArrayList emptyLocations = new ArrayList(); @@ -332,20 +329,19 @@ else if (shape instanceof SurfaceQuad) private static void assertSurfaceShapeEquals(AbstractSurfaceShape expected, AbstractSurfaceShape actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Actual is null", actual); - assertEquals("class", expected.getClass(), actual.getClass()); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Actual is null"); + assertEquals(expected.getClass(), actual.getClass(), "class"); int[] expectedEdgeIntervals = expected.getMinAndMaxEdgeIntervals(); int[] actualEdgeIntervals = actual.getMinAndMaxEdgeIntervals(); - assertEquals("isVisible", expected.isVisible(), actual.isVisible()); - assertEquals("attributes", expected.getAttributes(), actual.getAttributes()); - assertEquals("pathType", expected.getPathType(), actual.getPathType()); - assertEquals("texelsPerEdgeInterval", expected.getTexelsPerEdgeInterval(), actual.getTexelsPerEdgeInterval(), - 0.0); - assertEquals("minEdgeIntervals", expectedEdgeIntervals[0], actualEdgeIntervals[0]); - assertEquals("maxEdgeIntervals", expectedEdgeIntervals[1], actualEdgeIntervals[1]); + assertEquals(expected.isVisible(), actual.isVisible(), "isVisible"); + assertEquals(expected.getAttributes(), actual.getAttributes(), "attributes"); + assertEquals(expected.getPathType(), actual.getPathType(), "pathType"); + assertEquals(expected.getTexelsPerEdgeInterval(), actual.getTexelsPerEdgeInterval(), 0.0, "texelsPerEdgeInterval"); + assertEquals(expectedEdgeIntervals[0], actualEdgeIntervals[0], "minEdgeIntervals"); + assertEquals(expectedEdgeIntervals[1], actualEdgeIntervals[1], "maxEdgeIntervals"); if (expected instanceof SurfacePolyline) { @@ -354,27 +350,25 @@ private static void assertSurfaceShapeEquals(AbstractSurfaceShape expected, Abst } else if (expected instanceof SurfacePolygon) { - assertEquals("boundaries", ((SurfacePolygon) expected).boundaries, ((SurfacePolygon) actual).boundaries); + assertEquals(((SurfacePolygon) expected).boundaries, ((SurfacePolygon) actual).boundaries, "boundaries"); } else if (expected instanceof SurfaceSector) { - assertEquals("sector", ((SurfaceSector) expected).getSector(), ((SurfaceSector) actual).getSector()); + assertEquals(((SurfaceSector) expected).getSector(), ((SurfaceSector) actual).getSector(), "sector"); } else if (expected instanceof SurfaceEllipse) { - assertEquals("center", ((SurfaceEllipse) expected).getCenter(), ((SurfaceEllipse) actual).getCenter()); - assertEquals("majorRadius", ((SurfaceEllipse) expected).getMajorRadius(), - ((SurfaceEllipse) actual).getMajorRadius(), 0.0); - assertEquals("minorRadius", ((SurfaceEllipse) expected).getMinorRadius(), - ((SurfaceEllipse) actual).getMinorRadius(), 0.0); - assertEquals("heading", ((SurfaceEllipse) expected).getHeading(), ((SurfaceEllipse) actual).getHeading()); + assertEquals(((SurfaceEllipse) expected).getCenter(), ((SurfaceEllipse) actual).getCenter(), "center"); + assertEquals(((SurfaceEllipse) expected).getMajorRadius(), ((SurfaceEllipse) actual).getMajorRadius(), 0.0, "majorRadius"); + assertEquals(((SurfaceEllipse) expected).getMinorRadius(), ((SurfaceEllipse) actual).getMinorRadius(), 0.0, "minorRadius"); + assertEquals(((SurfaceEllipse) expected).getHeading(), ((SurfaceEllipse) actual).getHeading(), "heading"); } else if (expected instanceof SurfaceQuad) { - assertEquals("center", ((SurfaceQuad) expected).getCenter(), ((SurfaceQuad) actual).getCenter()); - assertEquals("width", ((SurfaceQuad) expected).getWidth(), ((SurfaceQuad) actual).getWidth(), 0.0); - assertEquals("height", ((SurfaceQuad) expected).getHeight(), ((SurfaceQuad) actual).getHeight(), 0.0); - assertEquals("heading", ((SurfaceQuad) expected).getHeading(), ((SurfaceQuad) actual).getHeading()); + assertEquals(((SurfaceQuad) expected).getCenter(), ((SurfaceQuad) actual).getCenter(), "center"); + assertEquals(((SurfaceQuad) expected).getWidth(), ((SurfaceQuad) actual).getWidth(), 0.0, "width"); + assertEquals(((SurfaceQuad) expected).getHeight(), ((SurfaceQuad) actual).getHeight(), 0.0, "height"); + assertEquals(((SurfaceQuad) expected).getHeading(), ((SurfaceQuad) actual).getHeading(), "heading"); } } @@ -386,7 +380,7 @@ private static void assertIterableEquals(String message, Iterable 0; i--) { tree.remove(i); - assertEquals("Item count incorrect ", countItemsInTree(tree), i - 1); + assertEquals(countItemsInTree(tree), i - 1, "Item count incorrect "); } } @@ -78,7 +74,7 @@ public void testIndividualRemoval() { tree.removeByName(Integer.toString(i)); Integer item = tree.getByName(Integer.toString(i)); - assertNull("Item not fully removed from tree ", item); + assertNull(item, "Item not fully removed from tree "); } } diff --git a/test/gov/nasa/worldwind/util/EGM96Test.java b/test/gov/nasa/worldwind/util/EGM96Test.java index fa012a8c80..5eeac5464b 100644 --- a/test/gov/nasa/worldwind/util/EGM96Test.java +++ b/test/gov/nasa/worldwind/util/EGM96Test.java @@ -29,15 +29,11 @@ package gov.nasa.worldwind.util; import gov.nasa.worldwind.geom.Angle; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.io.IOException; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class EGM96Test { /** @@ -92,7 +88,7 @@ public void testGetOffset_VerticalInterpolationTopGridPoint() throws IOException // Ensure the top latitude matches our expected latitude // This shows that the method has determined a row and column to query the dataset that corresponds with our // latitude value - assertEquals("latitude matches after index conversion", latitude.degrees, latTop, DELTA); + assertEquals(latitude.degrees, latTop, DELTA, "latitude matches after index conversion"); // Using the confirmed latitude value from above (via the topRow and leftCol values), find the actual node value double latGridPointOffset = egm96.gePostOffset(topRow, leftCol) / 100d; // the other method converts to meters @@ -100,7 +96,7 @@ public void testGetOffset_VerticalInterpolationTopGridPoint() throws IOException double latOffset = egm96.getOffset(latitude, longitude); // Ensure that they are equal - assertEquals("interpolated matches actual latitude", latGridPointOffset, latOffset, DELTA); + assertEquals(latGridPointOffset, latOffset, DELTA, "interpolated matches actual latitude"); } /** @@ -153,8 +149,8 @@ public void testGetOffset_VerticalInterpolationPoint() throws IOException // Ensure the top latitude matches our expected latitude // This shows that the method has determined a row and column to query the dataset that corresponds with our // latitude value - assertEquals("top latitude matches after index conversion", 38.75, latTop, DELTA); - assertEquals("bottom latitude matches after index conversion", 38.5, latBottom, DELTA); + assertEquals(38.75, latTop, DELTA, "top latitude matches after index conversion"); + assertEquals(38.5, latBottom, DELTA, "bottom latitude matches after index conversion"); // The calculated EGM96 offset double latOffset = egm96.getOffset(latitude, longitude); @@ -163,7 +159,7 @@ public void testGetOffset_VerticalInterpolationPoint() throws IOException + bottomOffsetValue; // Ensure that they are equal - assertEquals("interpolated matches actual latitude", manuallyCalculatedInterpolationValue, latOffset, DELTA); + assertEquals(manuallyCalculatedInterpolationValue, latOffset, DELTA, "interpolated matches actual latitude"); } /** @@ -208,7 +204,7 @@ public void testGetOffset_HorizontalInterpolationLeftGridPoint() throws IOExcept // Ensure the top latitude matches our expected latitude // This shows that the method has determined a row and column to query the dataset that corresponds with our // latitude value - assertEquals("longitude matches after index conversion", longitude.degrees + 360d, lonLeft, DELTA); + assertEquals(longitude.degrees + 360d, lonLeft, DELTA, "longitude matches after index conversion"); // Using the confirmed longitude value from above (via the topRow and leftCol values), find the actual node // value @@ -217,7 +213,7 @@ public void testGetOffset_HorizontalInterpolationLeftGridPoint() throws IOExcept double lonOffset = egm96.getOffset(latitude, longitude); // Ensure that they are equal - assertEquals("interpolated matches actual longitude", lonGridPointOffset, lonOffset, DELTA); + assertEquals(lonGridPointOffset, lonOffset, DELTA, "interpolated matches actual longitude"); } /** @@ -270,8 +266,8 @@ public void testGetOffset_HorizontalInterpolationPoint() throws IOException // Ensure the left longitude matches our expected longitude // This shows that the method has determined a row and column to query the dataset that corresponds with our // longitude value - assertEquals("left longitude matches after index conversion", -105d + 360d, lonLeft, DELTA); - assertEquals("right longitude matches after index conversion", -104.75 + 360d, lonRight, DELTA); + assertEquals(-105d + 360d, lonLeft, DELTA, "left longitude matches after index conversion"); + assertEquals(-104.75 + 360d, lonRight, DELTA, "right longitude matches after index conversion"); // The calculated EGM96 offset double lonOffset = egm96.getOffset(latitude, longitude); @@ -280,6 +276,6 @@ public void testGetOffset_HorizontalInterpolationPoint() throws IOException + leftOffsetValue; // Ensure that they are equal - assertEquals("interpolated matches actual longitude", manuallyCalculatedInterpolationValue, lonOffset, DELTA); + assertEquals(manuallyCalculatedInterpolationValue, lonOffset, DELTA, "interpolated matches actual longitude"); } } diff --git a/test/gov/nasa/worldwind/util/EntityMapTest.java b/test/gov/nasa/worldwind/util/EntityMapTest.java index 0caa8545b1..8d8895af14 100644 --- a/test/gov/nasa/worldwind/util/EntityMapTest.java +++ b/test/gov/nasa/worldwind/util/EntityMapTest.java @@ -28,13 +28,9 @@ package gov.nasa.worldwind.util; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class EntityMapTest { /** Test basic entity replacement. */ @@ -56,7 +52,7 @@ public void testAllReplacements() throws IllegalAccessException String expected = EntityMap.entityReplacements[i]; String actual = EntityMap.replaceAll(EntityMap.entityKeys[i]); - assertEquals("Failed entity replacement: " + EntityMap.entityKeys[i], expected, actual); + assertEquals(expected, actual, "Failed entity replacement: " + EntityMap.entityKeys[i]); } } diff --git a/test/gov/nasa/worldwind/util/HighResolutionTerrainTest.java b/test/gov/nasa/worldwind/util/HighResolutionTerrainTest.java index 563ea651bd..77268bca43 100644 --- a/test/gov/nasa/worldwind/util/HighResolutionTerrainTest.java +++ b/test/gov/nasa/worldwind/util/HighResolutionTerrainTest.java @@ -31,17 +31,15 @@ import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.globes.*; import gov.nasa.worldwind.terrain.*; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.util.*; import java.util.concurrent.*; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; -@Ignore -@RunWith(JUnit4.class) +@Disabled public class HighResolutionTerrainTest { private int GRID_SIZE = 50; @@ -92,7 +90,7 @@ public void exception(Exception e) if (currentIntersections.size() != previousIntersections.size()) { String msg = "Different intersection counts: current %d, previous %d\n"; - assertTrue(msg, currentIntersections.size() == previousIntersections.size()); + assertTrue(currentIntersections.size() == previousIntersections.size(), msg); } int item = -1; @@ -119,7 +117,7 @@ public void exception(Exception e) { String msg = "Different intersection points: " + j + ", " + currentIntersection[j] + ", " + previousIntersection[j] + ", " + position; - assertTrue(msg, currentIntersection[j].equals(previousIntersection[j])); + assertTrue(currentIntersection[j].equals(previousIntersection[j]), msg); } } } @@ -191,7 +189,7 @@ public void run() if (currentIntersections.size() != previousIntersections.size()) { String msg = "Different intersection counts: current %d, previous %d\n"; - assertTrue(msg, currentIntersections.size() == previousIntersections.size()); + assertTrue(currentIntersections.size() == previousIntersections.size(), msg); } int item = -1; @@ -218,7 +216,7 @@ public void run() { String msg = "Different intersection points: " + j + ", " + currentIntersection[j] + ", " + previousIntersection[j] + ", " + position; - assertTrue(msg, currentIntersection[j].equals(previousIntersection[j])); + assertTrue(currentIntersection[j].equals(previousIntersection[j]), msg); } } } diff --git a/test/gov/nasa/worldwind/util/HighResolutionTerrainTest2.java b/test/gov/nasa/worldwind/util/HighResolutionTerrainTest2.java index a8daa1d66a..1229b0af08 100644 --- a/test/gov/nasa/worldwind/util/HighResolutionTerrainTest2.java +++ b/test/gov/nasa/worldwind/util/HighResolutionTerrainTest2.java @@ -31,19 +31,17 @@ import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.globes.*; import gov.nasa.worldwind.terrain.HighResolutionTerrain; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.util.ArrayList; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.fail; /** * Checks for re-occurrence of WWJ-521. */ -@Ignore -@RunWith(JUnit4.class) +@Disabled public class HighResolutionTerrainTest2 { /** diff --git a/test/gov/nasa/worldwind/util/NetworkStatusTest.java b/test/gov/nasa/worldwind/util/NetworkStatusTest.java index 819e3de249..d653b18a8e 100644 --- a/test/gov/nasa/worldwind/util/NetworkStatusTest.java +++ b/test/gov/nasa/worldwind/util/NetworkStatusTest.java @@ -27,26 +27,25 @@ */ package gov.nasa.worldwind.util; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.net.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class NetworkStatusTest { private BasicNetworkStatus netStat; - @Before + @BeforeEach public void setUp() { this.netStat = new BasicNetworkStatus(); } - @After + @AfterEach public void tearDown() { } @@ -57,7 +56,7 @@ public void testSetAttemptLimit() int limit = 5; this.netStat.setAttemptLimit(limit); int ai = this.netStat.getAttemptLimit(); - assertEquals("Set attempt limit test ", ai, limit); + assertEquals(ai, limit, "Set attempt limit test "); } @Test @@ -66,23 +65,23 @@ public void testSetTryAgainInterval() long interval = 200; this.netStat.setTryAgainInterval(interval); long tai = this.netStat.getTryAgainInterval(); - assertEquals("Set try again interval test ", tai, interval); + assertEquals(tai, interval, "Set try again interval test "); } - @Ignore + @Disabled @Test public void testNetworkAvailable() { boolean tf = this.netStat.isNetworkUnavailable(); - assertFalse("Network unavailable test ", tf); + assertFalse(tf, "Network unavailable test "); } - @Ignore + @Disabled @Test public void testWorldWindAvailable() { boolean tf = this.netStat.isWorldWindServerUnavailable(); - assertFalse("WorldWind server unavailable test ", tf); + assertFalse(tf, "WorldWind server unavailable test "); } @Test @@ -91,7 +90,7 @@ public void testHostAvailable() throws MalformedURLException String hostName = "nasa.gov"; boolean tf = this.netStat.isHostUnavailable(new URL("https://" + hostName + "/path?abc=123")); - assertFalse("Host unavailable test ", tf); + assertFalse(tf, "Host unavailable test "); } @Test @@ -102,7 +101,7 @@ public void testHostLimitReached() throws MalformedURLException this.makeHostUnavailable(url); boolean tf = this.netStat.isHostUnavailable(url); - assertTrue("Host limit reached test ", tf); + assertTrue(tf, "Host limit reached test "); } @Test @@ -117,7 +116,7 @@ public void testHostLimitNotReached() throws MalformedURLException } boolean tf = this.netStat.isHostUnavailable(url); - assertFalse("Host limit not reached test ", tf); + assertFalse(tf, "Host limit not reached test "); } @Test @@ -129,7 +128,7 @@ public void testHostReavailable() throws MalformedURLException this.makeHostUnavailable(url); this.netStat.logAvailableHost(url); boolean tf = this.netStat.isHostUnavailable(url); - assertFalse("Host reavailable test ", tf); + assertFalse(tf, "Host reavailable test "); } @Test @@ -141,11 +140,11 @@ public void testHostTryAgain() throws MalformedURLException, InterruptedExceptio this.netStat.setTryAgainInterval(100); this.makeHostUnavailable(url); boolean tf = this.netStat.isHostUnavailable(url); - assertTrue("Host try again test A", tf); + assertTrue(tf, "Host try again test A"); Thread.sleep(netStat.getTryAgainInterval()); tf = this.netStat.isHostUnavailable(url); - assertFalse("Host try again test B", tf); + assertFalse(tf, "Host try again test B"); } @Test @@ -157,7 +156,7 @@ public void testNetworkAvailableAfterSuccessLogged() throws MalformedURLExceptio this.makeHostUnavailable(url); this.netStat.logAvailableHost(url); boolean tf = this.netStat.isHostUnavailable(url); - assertFalse("Network available after success test ", tf); + assertFalse(tf, "Network available after success test "); } private void makeHostUnavailable(URL url) diff --git a/test/gov/nasa/worldwind/util/OGLUtilTest.java b/test/gov/nasa/worldwind/util/OGLUtilTest.java index f6b8e5dbe8..99bf85f74b 100644 --- a/test/gov/nasa/worldwind/util/OGLUtilTest.java +++ b/test/gov/nasa/worldwind/util/OGLUtilTest.java @@ -30,17 +30,15 @@ import com.jogamp.opengl.util.texture.TextureData; import gov.nasa.worldwind.Configuration; -import org.junit.*; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import com.jogamp.opengl.*; import java.io.*; import java.net.URL; -import static org.junit.Assert.assertEquals; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.assertEquals; public class OGLUtilTest { private static final String PNG_FILE = "./src/images/earth-map-512x256.png"; @@ -49,13 +47,13 @@ public class OGLUtilTest private GLProfile glProfile; - @Before + @BeforeEach public void setUp() { this.glProfile = Configuration.getMaxCompatibleGLProfile(); } - @After + @AfterEach public void tearDown() { this.glProfile = null; diff --git a/test/gov/nasa/worldwind/util/WWMathTest.java b/test/gov/nasa/worldwind/util/WWMathTest.java index 553cfe4077..949901db7c 100644 --- a/test/gov/nasa/worldwind/util/WWMathTest.java +++ b/test/gov/nasa/worldwind/util/WWMathTest.java @@ -28,14 +28,10 @@ package gov.nasa.worldwind.util; -import static org.junit.Assert.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; import gov.nasa.worldwind.geom.Vec4; - -@RunWith(JUnit4.class) public class WWMathTest { private static final double DELTA = 1e-9; @@ -50,17 +46,17 @@ public void testParseTimeString() { Vec4 v3 = new Vec4(12, -23, 13); Vec4 expectedNormal = new Vec4(0.8725060159497201, -0.48860336893184325, 0.0); Vec4 normal = WWMath.computeTriangleNormal(v1, v2, v3); - assertEquals("Normal computation 1 X", expectedNormal.x, normal.x, DELTA); - assertEquals("Normal computation 1 Y", expectedNormal.y, normal.y, DELTA); - assertEquals("Normal computation 1 Z", expectedNormal.z, normal.z, DELTA); + assertEquals(expectedNormal.x, normal.x, DELTA, "Normal computation 1 X"); + assertEquals(expectedNormal.y, normal.y, DELTA, "Normal computation 1 Y"); + assertEquals(expectedNormal.z, normal.z, DELTA, "Normal computation 1 Z"); v1 = new Vec4(-12, 12, 26); v2 = new Vec4(23, -23, 2); v3 = new Vec4(13, 13, 13); expectedNormal = new Vec4(0.4612242682795252, -0.1396190373706287, 0.8762298207398077); normal = WWMath.computeTriangleNormal(v1, v2, v3); - assertEquals("Normal computation 2 X", expectedNormal.x, normal.x, DELTA); - assertEquals("Normal computation 2 Y", expectedNormal.y, normal.y, DELTA); - assertEquals("Normal computation 2 Z", expectedNormal.z, normal.z, DELTA); + assertEquals(expectedNormal.x, normal.x, DELTA, "Normal computation 2 X"); + assertEquals(expectedNormal.y, normal.y, DELTA, "Normal computation 2 Y"); + assertEquals(expectedNormal.z, normal.z, DELTA, "Normal computation 2 Z"); } } diff --git a/test/gov/nasa/worldwind/util/WWUtilTest.java b/test/gov/nasa/worldwind/util/WWUtilTest.java index 347e968d1a..9c3b2f2871 100644 --- a/test/gov/nasa/worldwind/util/WWUtilTest.java +++ b/test/gov/nasa/worldwind/util/WWUtilTest.java @@ -28,15 +28,11 @@ package gov.nasa.worldwind.util; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; import java.util.*; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class WWUtilTest { /** Test parsing time strings. */ diff --git a/test/gov/nasa/worldwind/view/BasicOrbitViewTest.java b/test/gov/nasa/worldwind/view/BasicOrbitViewTest.java index be6ba61a92..097e8fa06b 100644 --- a/test/gov/nasa/worldwind/view/BasicOrbitViewTest.java +++ b/test/gov/nasa/worldwind/view/BasicOrbitViewTest.java @@ -29,13 +29,9 @@ import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.view.orbit.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.jupiter.api.Test; -import static org.junit.Assert.*; - -@RunWith(JUnit4.class) +import static org.junit.jupiter.api.Assertions.*; public class BasicOrbitViewTest { ////////////////////////////////////////////////////////// @@ -235,36 +231,35 @@ private static void assignNullValues(OrbitView orbitView) private static void assertOrbitViewEquals(OrbitView expected, OrbitView actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Actual is null", actual); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Actual is null"); - assertEquals("center", expected.getCenterPosition(), actual.getCenterPosition()); - assertEquals("heading", expected.getHeading(), actual.getHeading()); - assertEquals("pitch", expected.getPitch(), actual.getPitch()); - assertEquals("zoom", expected.getZoom(), actual.getZoom(), 0.0); - assertEquals("fieldOfView", expected.getFieldOfView(), actual.getFieldOfView()); + assertEquals(expected.getCenterPosition(), actual.getCenterPosition(), "center"); + assertEquals(expected.getHeading(), actual.getHeading(), "heading"); + assertEquals(expected.getPitch(), actual.getPitch(), "pitch"); + assertEquals(expected.getZoom(), actual.getZoom(), 0.0, "zoom"); + assertEquals(expected.getFieldOfView(), actual.getFieldOfView(), "fieldOfView"); - assertEquals("detectCollisions", expected.isDetectCollisions(), actual.isDetectCollisions()); - assertEquals("nearClipDistance", expected.getNearClipDistance(), actual.getNearClipDistance(), 0.0); - assertEquals("farClipDistance", expected.getFarClipDistance(), actual.getFarClipDistance(), 0.0); + assertEquals(expected.isDetectCollisions(), actual.isDetectCollisions(), "detectCollisions"); + assertEquals(expected.getNearClipDistance(), actual.getNearClipDistance(), 0.0, "nearClipDistance"); + assertEquals(expected.getFarClipDistance(), actual.getFarClipDistance(), 0.0, "farClipDistance"); assertOrbitViewLimitsEquals(expected.getOrbitViewLimits(), actual.getOrbitViewLimits()); } private static void assertOrbitViewLimitsEquals(OrbitViewLimits expected, OrbitViewLimits actual) { - assertNotNull("Expected is null", expected); - assertNotNull("Actual is null", actual); + assertNotNull(expected, "Expected is null"); + assertNotNull(actual, "Actual is null"); - assertEquals("centerLocationLimits", expected.getCenterLocationLimits(), actual.getCenterLocationLimits()); + assertEquals(expected.getCenterLocationLimits(), actual.getCenterLocationLimits(), "centerLocationLimits"); for (int i = 0; i < 2; i++) { - assertEquals("centerElevationLimits[" + i + "]", expected.getCenterElevationLimits()[i], - actual.getCenterElevationLimits()[i], 0.0); - assertEquals("headingLimits[" + i + "]", expected.getHeadingLimits()[i], actual.getHeadingLimits()[i]); - assertEquals("pitchLimits[" + i + "]", expected.getPitchLimits()[i], actual.getPitchLimits()[i]); - assertEquals("zoomLimits[" + i + "]", expected.getZoomLimits()[i], actual.getZoomLimits()[i], 0.0); + assertEquals(expected.getCenterElevationLimits()[i], actual.getCenterElevationLimits()[i], 0.0, "centerElevationLimits[" + i + "]"); + assertEquals(expected.getHeadingLimits()[i], actual.getHeadingLimits()[i], "headingLimits[" + i + "]"); + assertEquals(expected.getPitchLimits()[i], actual.getPitchLimits()[i], "pitchLimits[" + i + "]"); + assertEquals(expected.getZoomLimits()[i], actual.getZoomLimits()[i], 0.0, "zoomLimits[" + i + "]"); } } }