{"id":18141572,"url":"https://github.com/skjolber/async-stax-utils","last_synced_at":"2025-04-22T13:19:29.722Z","repository":{"id":52474450,"uuid":"78448404","full_name":"skjolber/async-stax-utils","owner":"skjolber","description":"Asynchronous StAX-utils","archived":false,"fork":false,"pushed_at":"2023-10-13T22:57:39.000Z","size":339,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-22T13:19:04.747Z","etag":null,"topics":["aalto-xml","asynchronous","filter","io","xml","xpath"],"latest_commit_sha":null,"homepage":null,"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/skjolber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-09T16:47:03.000Z","updated_at":"2023-10-13T22:43:08.000Z","dependencies_parsed_at":"2022-08-28T08:41:19.953Z","dependency_job_id":null,"html_url":"https://github.com/skjolber/async-stax-utils","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skjolber%2Fasync-stax-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skjolber%2Fasync-stax-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skjolber%2Fasync-stax-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skjolber%2Fasync-stax-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skjolber","download_url":"https://codeload.github.com/skjolber/async-stax-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250246730,"owners_count":21398919,"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","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":["aalto-xml","asynchronous","filter","io","xml","xpath"],"created_at":"2024-11-01T17:07:38.096Z","updated_at":"2025-04-22T13:19:29.697Z","avatar_url":"https://github.com/skjolber.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# async-stax-utils\nThis project hosts some simple utilities for dealing with XML streams in an asynchronous way. This is achieved through the use of the [Aalto-xml] asynchronous XML-parser.\n\nCurrently the main focus is on 'easedropping' scenarios like validation, logging and analytics, where input/output-stream contents is unaffected for up/downstream peers.\n\nUsers of this library will benefit from\n\n  * Passthrough Input- and Outputstream read-/write-delegates with end-of-stream callback\n  * Streaming XML-processing\n    * Schema validation\n    * Max text/CDATA-node and document-length filtering\n  * Synchronous processing with asynchronous fallback based on configurable cache size.\n\nBugs, feature suggestions and help requests can be filed with the [issue-tracker].\n\n## License\n[Apache 2.0]\n\n# Obtain\nThe project is based on [Maven] and is available at Maven central repository.\n\n\u003cdetails\u003e\n  \u003csummary\u003eMaven coordinates\u003c/summary\u003e\n  \nAdd\n \n```xml\n\u003casync-stax-utils.version\u003e1.0.3\u003c/async-stax-utils.version\u003e\n```\n\nand\n\n```xml\n\u003cdependency\u003e\n\t\u003cgroupId\u003ecom.github.skjolber\u003c/groupId\u003e\n\t\u003cartifactId\u003easync-stax-utils\u003c/artifactId\u003e\n    \u003cversion\u003e${async-stax-utils.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003c/details\u003e\n\n# Usage\nThe asynchronous nature adds some processing overhead and setup complexity compared to regular synchronous approach. If you prefer skipping to code examples, see [unit tests](src/test/java/com/github/skjolber/asyncstaxutils). \n\n## StreamProcessor\nThe `StreamProcessor` is a simple listener interface for passing bytes captured from `OutputStream` and  `InputStream`.\n\n```java\nvoid payload(byte[] buffer, int offset, int length);\nvoid close();\n```\n\n## Delegate streams\nCreate a callback,\n\n```java\nDelegateStreamCallback callback = new DelegateStreamCallback() {\n\tpublic void closed(StreamProcessor processor, boolean success) {\n\t\tSystem.out.println(\"Stream closed\");\n\t}\n}\n```\nfor end-of-stream logic. Take a `StreamProcessor` and create a passthrough `OutputStream` and/or `InputStream` using\n\n```java\nOutputStream dos = new DelegateOutputStream(out, streamProcessor, callback);\n```\n\nor input\n\n```java\nInputStream dis = new DelegateOutputStream(in, streamProcessor, callback);\n```\n\nThen pass these up/down your processing pipe. Then `dis.read(..)` or `dos.write(..)` then invokes our `StreamProcessor` and finally `dis.close()` or `dos.close()` triggers a call to`DelegateStreamCallback`.\n\nThe default `StreamProcessor` for XML is `DefaultXMLStreamProcessor` which just parses XML events until the current buffer is exhausted.\n## StreamFilterProcessorFactory\n`StreamFilterProcessorFactory` is a pattern for cases for capturing filtered output in a `Writer`, for example for logging. It supports both asynchronous \nand synchronous usage.\n \n```java\nStreamFilterProcessorFactory streamFilterProcessorFactory = ...; // init\nfinal Writer output = new StringWriter(8 * 1024); // for use in callback\nStreamProcessor streamProcessor = factory.async(output);\n```\n\n### Filters\nFiltering is performed via the `XMLStreamFilter` interface, which consists of a single method\n\n```java\nvoid filter(XMLStreamReader2 reader, XMLStreamWriter2 writer) throws XMLStreamException;\n```\n\n### AccumulatorStreamFilterProcessor\nThis processor tries to avoid the overhead the asynchronous processing for documents of limited size. It uses a cache and only creates a (stateful) async filter for documents which exceed a certain threshold. For\n\n```java\nint maxCacheLengthBytes = 1024;\n```\nconstruct the `AccumulatorStreamFilterProcessor` using \n\n```java\nStreamProcessor streamProcessor = new AccumulatorStreamFilterProcessor(maxCacheLengthBytes, streamProcessorFactory, output);\n```\n\nfinally make the delegate input\n\n```java\nDelegateInputStream dis = new DelegateInputStream(bin, streamProcessor, callback);\n```\nor output\n\n```java\nDelegateOutputStream dis = new DelegateOutputStream(bin, listener, callback);\n```\n\nstreams and pass them up or down your pipe.\n\n# History\n- 1.0.3: Maintenance release; bumped dependencies and added modules\n- 1.0.2: Better class names and packages, some some reuse of XML-related processors.\n- 1.0.1: Better document-size length filtering.\n- 1.0.0: Initial release.\n\n[Apache 2.0]:          \thttp://www.apache.org/licenses/LICENSE-2.0.html\n[Aalto-xml]:\t\t\thttps://github.com/FasterXML/aalto-xml\n[issue-tracker]:       \thttps://github.com/skjolber/async-stax-utils/issues\n[Maven]:                http://maven.apache.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskjolber%2Fasync-stax-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskjolber%2Fasync-stax-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskjolber%2Fasync-stax-utils/lists"}