{"id":31910436,"url":"https://github.com/filip26/polymorph-tree","last_synced_at":"2025-10-13T16:24:10.284Z","repository":{"id":314327394,"uuid":"1053018436","full_name":"filip26/polymorph-tree","owner":"filip26","description":"Uniform API to read/write tree data models - cross-format, cross-library.","archived":false,"fork":false,"pushed_at":"2025-10-13T11:37:16.000Z","size":437,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-13T16:24:08.946Z","etag":null,"topics":["cbor","jackson-databind","jakarta-json-api","json-api"],"latest_commit_sha":null,"homepage":"https://apicatalog.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/filip26.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-08T21:52:34.000Z","updated_at":"2025-10-13T11:37:12.000Z","dependencies_parsed_at":"2025-09-11T22:12:35.519Z","dependency_job_id":"2dfcf0d8-2823-43fc-8e32-cdc32e897b5c","html_url":"https://github.com/filip26/polymorph-tree","commit_stats":null,"previous_names":["filip26/tree-io","filip26/polymorph-tree"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/filip26/polymorph-tree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filip26%2Fpolymorph-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filip26%2Fpolymorph-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filip26%2Fpolymorph-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filip26%2Fpolymorph-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filip26","download_url":"https://codeload.github.com/filip26/polymorph-tree/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filip26%2Fpolymorph-tree/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279016065,"owners_count":26085799,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cbor","jackson-databind","jakarta-json-api","json-api"],"created_at":"2025-10-13T16:24:06.966Z","updated_at":"2025-10-13T16:24:10.277Z","avatar_url":"https://github.com/filip26.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌳 Tree I/O\n\n**Uniform API to read/write tree data models — cross-format, cross-library.**\n\n**tree-io** provides a consistent abstraction for working with **tree-like data structures**.  It is **format-agnostic** (JSON, YAML, CBOR, …) and **library-agnostic** (Jackson, Gson, Jakarta, …),  allowing you to **read, manipulate, and write trees uniformly** without depending on a specific parser or serializer.\n\n## ✨ Features\n\n- 🌐 Uniform, library-agnostic API for tree data processing\n- 🗂️ Supports multiple formats: JSON, YAML, CBOR\n- 🔌 Works with Jackson, Gson, Jakarta, and other libraries\n- 🛠️ Extensible adapter model for adding new formats or libraries\n\n## 🏗️ Use Cases\n\n- Uniform processing of tree-structured data\n- Building library-agnostic processors and pipelines\n- Manipulating hierarchical data in a consistent way\n\n## 🔌 Implementations of Tree I/O API\n\n Artifact               | Version | Javadoc\n-----------------------|---------|---------------\n**Tree I/O API**           | [![Maven Central](https://img.shields.io/maven-central/v/com.apicatalog/tree-io-api.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.apicatalog%20AND%20a:tree-io-api) | [![javadoc](https://javadoc.io/badge2/com.apicatalog/tree-io-api/javadoc.svg)](https://javadoc.io/doc/com.apicatalog/tree-io-api) \n Jakarta JSON API      | [![Maven Central](https://img.shields.io/maven-central/v/com.apicatalog/tree-io-jakarta.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.apicatalog%20AND%20a:tree-io-jakarta) | [![javadoc](https://javadoc.io/badge2/com.apicatalog/tree-io-jakarta/javadoc.svg)](https://javadoc.io/doc/com.apicatalog/tree-io-jakarta) \n Jackson 2 Tree Model  | [![Maven Central](https://img.shields.io/maven-central/v/com.apicatalog/tree-io-jackson2.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.apicatalog%20AND%20a:tree-io-jackson2) | [![javadoc](https://javadoc.io/badge2/com.apicatalog/tree-io-jackson2/javadoc.svg)](https://javadoc.io/doc/com.apicatalog/tree-io-jackson2) \n CBOR                  | [![Maven Central](https://img.shields.io/maven-central/v/com.apicatalog/tree-io-cbor.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:com.apicatalog%20AND%20a:tree-io-cbor) | [![javadoc](https://javadoc.io/badge2/com.apicatalog/tree-io-cbor/javadoc.svg)](https://javadoc.io/doc/com.apicatalog/tree-io-cbor) \n\n## Examples \n\n### High-Level Transformation\nThe most common use case is a full transformation from a source to a destination.\n\n```javascript\n// Have a source object (e.g., a Map) and a destination (e.g., a JsonGenerator)\nMap\u003cString, Object\u003e source = Map.of(\"hello\", \"world\");\nJsonGenerator destination = ... ;\n\n// Create an adapter for the source and a writer for the destination\nvar adapter = new NativeAdapter();\nvar jsonWriter = new Jackson2Writer(destination);\nvar cborWriter = new CborWriter(destination);\n\n// Run the transformation with a single call\njsonWriter.node(source, adapter);\n// or/and\ncborWriter.node(source, adapter);\n```\n\n### Direct Node Inspection using NodeAdapter\n\nUse a NodeAdapter directly when you need to read, inspect, or extract specific values from a tree structure without traversing the entire tree.\n\n```javascript\n// Given any 'node' object and a suitable 'adapter'...\n\n// To inspect and process it safely:\n\n// 1. Check for structural types first.\nif (adapter.isMap(node)) {\n    // If it's a map, iterate its entries.\n    for (Entry\u003c?, ?\u003e entry : adapter.entries(node)) {\n        // ... process key and value recursively\n    }\n\n} else if (adapter.isCollection(node)) {\n    // If it's a collection, iterate its elements.\n    for (Object element : adapter.elements(node)) {\n        // ... process element recursively\n    }\n\n// 2. Then, check for scalar types.\n} else if (adapter.isString(node)) {\n    String value = adapter.stringValue(node);\n\n} else if (adapter.isNumber(node)) {\n    // For numbers, check for the specific type before extracting.\n    if (adapter.isIntegral(node)) {\n        long intValue = adapter.longValue(node);\n    } else {\n        BigDecimal decimalValue = adapter.decimalValue(node);\n    }\n\n} else if (adapter.isNull(node)) {\n    // It's a null value.\n}\n```\n\n### Manual Traversal using NodeVisitor\nFor complex processing like searching or validation, you can manually iterate through the tree using the step() method of a NodeVisitor.\n\n```javascript\n// Given a source object and a suitable adapter...\nObject source = ... ;\nNodeAdapter adapter = ... ;\n\n// 1. Create the visitor instance.\nNodeVisitor visitor = NodeVisitor.of(source, adapter);\n\n// 2. Loop step-by-step through every node in the tree.\nwhile (visitor.step()) {\n\n    // 3. Inspect the visitor's state after each step.\n    Object node = visitor.currentNode();\n    NodeType type = visitor.currentNodeType();\n    Context context = visitor.currentNodeContext();\n\n    // 4. Perform actions based on the node's role in the tree.\n    switch (context) {\n\n        case ROOT:\n            // Process the top-level node.\n            break;\n\n        case PROPERTY_KEY:\n            // The current node is a key in a map.\n            // The next step() will move to its value.\n            break;\n\n        case PROPERTY_VALUE:\n            // The current node is a value in a map.\n            break;\n\n        case COLLECTION_ELEMENT:\n            // The current node is an element in a collection.\n            break;\n\n        case END:\n            // A synthetic marker showing a map or collection has ended.\n            break;\n    }\n}\n```\n\n## 📦 Artifacts\n\n```xml\n\u003c!-- Core API: uniform interfaces implemented by all adapters --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.apicatalog\u003c/groupId\u003e\n    \u003cartifactId\u003etree-io-api\u003c/artifactId\u003e\n    \u003cversion\u003e${tree-io.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- Available adapters: include the one(s) matching your use case --\u003e\n\n\u003c!-- Jakarta JSON API adapter --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.apicatalog\u003c/groupId\u003e\n    \u003cartifactId\u003etree-io-jakarta\u003c/artifactId\u003e\n    \u003cversion\u003e${tree-io.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- Jackson 2 Tree Model adapter --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.apicatalog\u003c/groupId\u003e\n    \u003cartifactId\u003etree-io-jackson2\u003c/artifactId\u003e\n    \u003cversion\u003e${tree-io.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- CBOR adapter --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.apicatalog\u003c/groupId\u003e\n    \u003cartifactId\u003etree-io-cbor\u003c/artifactId\u003e\n    \u003cversion\u003e${tree-io.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Please submit a pull request.\n\n### Building\n\nFork and clone the repository, then build with Maven:\n\n```bash\n\u003e cd tree-io\n\u003e mvn package\n```\n\n## 💼 Commercial Support\n\nCommercial support and consulting are available.  \nFor inquiries, please contact: filip26@gmail.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilip26%2Fpolymorph-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilip26%2Fpolymorph-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilip26%2Fpolymorph-tree/lists"}