### Usage: Implementing XmlChunker.Listener Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Example of implementing the XmlChunker.Listener interface to handle pre-target start elements and process chunks. ```java XmlChunker.parse(inputStream, "UTF-8", 2, new XmlChunker.Listener() { @Override public void onPreTargetStart(int depth, StartElement element) { System.out.println("Pre-target element: " + element.getName()); } @Override public boolean onChunk(Element element) { return true; // continue processing } }); ``` -------------------------------- ### Jonix Configuration: Per-Source Setup Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Illustrates a pattern for per-source setup in Jonix configuration. This enables customized settings for individual data sources. ```java // Pattern for per-source setup JonixFacade facade = JonixFacade.create(config.sourceConfig("source1", sourceConfig)); ``` -------------------------------- ### Usage Example for equal() Method Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md An example illustrating the use of the equal() method for an exact string comparison of an ONIX element's value, such as an ISBN. ```java if (isbn.equal("978-0-123456-78-9")) { // exact match } ``` -------------------------------- ### Example CustomUnifier Implementation Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Provides an example implementation of the CustomUnifier interface. This class, MyUnifier, demonstrates how to extract specific fields like ISBN from both ONIX 2 and ONIX 3 product data and how to create custom unified product, header, and record objects. ```java public class MyUnifier implements CustomUnifier { @Override public MyRecord unifiedRecord(JonixRecord rawRecord) { return new MyRecord(rawRecord, unifiedProduct(rawRecord.product)); } @Override public MyProduct unifiedProduct(OnixProduct onixProduct) { if (onixProduct.onixVersion() == OnixVersion.ONIX2) { return extractProduct2((com.tectonica.jonix.onix2.Product) onixProduct); } else { return extractProduct3((com.tectonica.jonix.onix3.Product) onixProduct); } } @Override public MyProduct extractProduct2(com.tectonica.jonix.onix2.Product product) { MyProduct p = new MyProduct(); p.isbn = product.productIdentifiers() .find(ProductIdentifierTypes.ISBN_13) .map(pi -> pi.idValue().value) .orElse(null); return p; } @Override public MyProduct extractProduct3(com.tectonica.jonix.onix3.Product product) { MyProduct p = new MyProduct(); p.isbn = product.productIdentifiers() .find(ProductIdentifierTypes.ISBN_13) .map(pi -> pi.idValue().value) .orElse(null); return p; } @Override public MyHeader unifiedHeader(OnixHeader onixHeader) { MyHeader h = new MyHeader(); // extract only needed header fields return h; } } ``` -------------------------------- ### Jonix XML Direct Usage Example 1 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt A direct usage example for the Jonix XML API, demonstrating basic parsing or manipulation. ```java // Example code for direct XML usage String xml = "value"; // ... process xml using Jonix XML API ... ``` -------------------------------- ### Structured Logging with SLF4j Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-error-handling.md Use structured logging to provide context for errors and informational messages. This example shows how to log source start events and errors during record processing. ```java records.onSourceStart(src -> { LOGGER.info("Starting source", "source", src.sourceName(), "version", src.onixVersion(), "release", src.onixRelease()); }); records.stream().forEach(record -> { try { processRecord(record); } catch (Exception e) { String ref = Jonix.toBaseProduct(record.product) .info.recordReference; LOGGER.error("Error processing record", "reference", ref, "error", e.getMessage(), e); } }); ``` -------------------------------- ### Get First Resource Link Value Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Example of safely retrieving the first resource link value from a list of resource versions. ```java String resourceLink = resourceVersions .firstOrEmpty() .resourceLinks() .firstValueOrNull(); ``` -------------------------------- ### Custom Unifier Interface Example Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides an example of defining a custom unifier interface. This allows for flexible and tailored data unification logic. ```java interface CustomUnifier { T unify(T data1, T data2); } ``` -------------------------------- ### Jonix XML Direct Usage Example 3 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt A third direct usage example for the Jonix XML API, offering further illustration of its capabilities. ```java // Third example for direct XML usage // ... yet another XML processing scenario ... ``` -------------------------------- ### Jonix XML Direct Usage Example 2 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt A second direct usage example for the Jonix XML API, potentially showcasing a different feature or scenario. ```java // Another example for direct XML usage // ... different XML processing scenario ... ``` -------------------------------- ### Example XML Structure with Depth Levels Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Illustrates an example XML structure and the corresponding depth levels for ONIX messages. This helps in understanding how targetDepth affects chunking. ```xml
...
(chunk at targetDepth=2) ... ... (chunk at targetDepth=2) ...
``` -------------------------------- ### Usage Example for is() Method Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md An example demonstrating how to use the is() method to compare an ONIX element's value against a specific enum constant. ```java if (titleType.is(TitleTypes.Distinctive_title_book)) { // process distinctive title } ``` -------------------------------- ### XmlChunker.Listener.onPreTargetStart Method Signature Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Signature for the callback method invoked before an XML element at the target depth starts. ```java default void onPreTargetStart(int depth, StartElement element) ``` -------------------------------- ### XML Depth Level Example Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides an example illustrating XML depth levels. This is crucial for understanding hierarchical XML structures during parsing. ```xml ``` -------------------------------- ### Example: Configure and Use Tabulation Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Demonstrates the typical usage pattern of creating a Tabulation instance, adding various field tabulators (ID, Title, Contributors, Price), retrieving headers, and generating a row for a product. ```java Tabulation tabulation = Tabulation.create(); tabulation.add(new TitleFieldTabulator()) .add(new AuthorFieldTabulator()) .add(new PriceFieldTabulator()); ``` ```java Tabulation tabulation = Tabulation.create() .add(BaseFieldTabulator.ID) .add(BaseFieldTabulator.TITLE) .add(BaseFieldTabulator.CONTRIBUTORS) .add(BaseFieldTabulator.PRICE); ``` ```java List headers = tabulation.header(); csvWriter.writeRecord(headers.toArray(new String[0])); ``` ```java List row = tabulation.row(baseProduct); csvWriter.writeRecord(row.toArray(new String[0])); ``` -------------------------------- ### OnixVersion Usage Example Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Demonstrates how to use the OnixVersion enum to perform version-specific logic, such as converting a record to an ONIX3 product. ```java if (record.product.onixVersion() == OnixVersion.ONIX3) { com.tectonica.jonix.onix3.Product p = Jonix.toProduct3(record); } ``` -------------------------------- ### Build Jonix from Source Source: https://github.com/zach-m/jonix/blob/master/README.md Steps to clone the Jonix repository and build it locally using Maven. Ensure Maven and JDK requirements are met before starting. ```shell # verify requirements: Maven-version >= 3.3.9 && JDK-version >= 9 mvn -version # clone the repository git clone https://github.com/zach-m/jonix.git # build cd jonix mvn clean mv -P release install ``` -------------------------------- ### Usage: Parsing XML with XmlChunker Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Example demonstrating how to use XmlChunker.parse to process a large XML file and handle chunks. ```java try (InputStream is = new FileInputStream("large.xml")) { XmlChunker.parse(is, "UTF-8", 2, new XmlChunker.Listener() { @Override public boolean onChunk(Element element) { // Process chunk String tagName = element.getTagName(); String value = element.getTextContent(); return true; // continue } }); } ``` -------------------------------- ### Usage: Implementing XmlChunker.Listener.onChunk Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Example of implementing the onChunk method to process an XML sub-tree and control parsing continuation. ```java new XmlChunker.Listener() { @Override public boolean onChunk(Element element) { System.out.println("Processing chunk: " + element.getTagName()); // Process the chunk... return true; // continue } } ``` -------------------------------- ### Using a Custom Unifier with Jonix Source Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Shows how to integrate a custom unifier into the Jonix processing pipeline. This example demonstrates creating an instance of a custom unifier and using it with the Jonix.source() method to process records and apply the custom unification logic. ```java MyUnifier unifier = new MyUnifier(); Jonix.source(file) .stream() .map(record -> JonixUnifier.unifyRecord(record, unifier)) .forEach(rec -> { // use custom unified record }); ``` -------------------------------- ### Tabulation.create() Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Creates a new empty Tabulation instance. This is the starting point for configuring how ONIX products will be flattened. ```APIDOC ## Tabulation.create() ### Description Creates a new empty Tabulation for type P. This method initializes the tabulation process, allowing subsequent addition of field tabulators. ### Method `public static

Tabulation

create()` ### Returns `Tabulation

` - An empty tabulation ready for field addition. ### Usage ```java Tabulation tabulation = Tabulation.create(); tabulation.add(new TitleFieldTabulator()); ``` ``` -------------------------------- ### JonixRecords Event Handling Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Illustrates the setup of event handlers for the JonixRecords class. This allows for custom processing of events related to record additions or changes. ```java records.onAdd(record -> { /* handle add */ }); records.onRemove(record -> { /* handle remove */ }); ``` -------------------------------- ### Jonix Error Handling: Empty Collections Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates handling of empty collections, another common edge case. This example shows how to safely check and process collections. ```java // Handling empty collections if (record.getContributors().isEmpty()) { // Handle no contributors } ``` -------------------------------- ### Create a New Tabulation Instance Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Creates a new empty Tabulation instance for a specific product type. This is the starting point for configuring data extraction. ```java public static

Tabulation

create() ``` -------------------------------- ### Find ISBN-13 Product Identifier Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Example of using the find method to locate a specific ProductIdentifier by its type, such as ISBN_13. ```java Optional isbn = product.productIdentifiers() .find(ProductIdentifierTypes.ISBN_13); ``` -------------------------------- ### Register Source Start Event Handler Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Registers a callback to be executed when processing of a new ONIX source begins, after the header has been read. The handler receives details about the current ONIX source. ```java public JonixRecords onSourceStart(JonixRecords.OnSourceEvent handler) ``` ```java records.onSourceStart(src -> { System.out.printf("Processing %s (ONIX %s)%n", src.sourceName(), src.onixVersion()); src.header().ifPresent(h -> { System.out.println("Sent from: " + Jonix.toBaseHeader(h).senderName); }); }); ``` -------------------------------- ### Get Product Label Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Retrieves a human-readable label for the product, typically the first title or record reference. Use this to display a concise identifier for a product. ```java public String getLabel() ``` ```java System.out.println(bp.getLabel()); ``` -------------------------------- ### Jonix Error Handling: ONIX Release Mismatches Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Illustrates handling of ONIX release mismatches, a specific challenge in bibliographic data processing. This example shows how to detect and manage version conflicts. ```java // Handling ONIX release mismatches if (!record.getVersion().equals("3.0")) { // Handle version mismatch } ``` -------------------------------- ### Parse Custom XML with XmlChunker Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Demonstrates how to use XmlChunker to parse a custom XML input stream. It shows how to set the target depth and implement a listener to process chunks and pre-target start elements. ```java try (InputStream is = new FileInputStream("data.xml")) { XmlChunker.parse(is, "UTF-8", 2, new XmlChunker.Listener() { @Override public void onPreTargetStart(int depth, StartElement element) { if ("Metadata".equals(element.getName().getLocalPart())) { System.out.println("Found metadata section"); } } @Override public boolean onChunk(Element element) { System.out.println("Processing: " + element.getTagName()); // Extract data from chunk NodeList children = element.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node node = children.item(i); if (node instanceof Element) { Element child = (Element) node; System.out.println(" " + child.getTagName() + "=" + child.getTextContent()); } } return true; // continue parsing } }); } catch (Exception e) { e.printStackTrace(); } ``` -------------------------------- ### Find Distinctive Title by Type Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Example of finding a specific title composite, like a distinctive title, using its TitleTypes key. ```java Optional distinctiveTitle = product.titleDetails() .find(TitleTypes.Distinctive_title_book); ``` -------------------------------- ### Conditional XML Chunk Processing with XmlChunker Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Illustrates how to conditionally process XML chunks based on specific criteria. The example shows how to check an attribute value and only process chunks that meet the condition. ```java XmlChunker.parse(is, "UTF-8", 2, new XmlChunker.Listener() { @Override public void onPreTargetStart(int depth, StartElement element) { // Look ahead at shallow elements } @Override public boolean onChunk(Element element) { // Only process chunks matching criteria String id = element.getAttribute("ID"); if (id != null && id.startsWith("SPECIAL_")) { processSpecialChunk(element); return true; } return true; // continue even if skipped } }); ``` -------------------------------- ### Using BaseTabulation.ALL Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Demonstrates how to obtain the default ALL tabulator for BaseProduct. ```java Tabulation<BaseProduct> tabulation = BaseTabulation.ALL; ``` -------------------------------- ### Convert ONIX to CSV using Jonix Streaming Source: https://github.com/zach-m/jonix/blob/master/README.md This example demonstrates converting a list of ONIX files to CSV format. It utilizes Jonix's streaming features, including source storage for passing variables, stream control methods, and custom unification. Error handling is also shown. ```java public static void onixToCsv(List<String> fileNames) { Jonix.source(fileNames.stream().map(File::new).toList()) .onSourceStart(source -> { String csvFileName = source.sourceName(); System.out.println("Creating " + csvFileName + ".."); final CsvWriter csv = new CsvWriter(csvFileName); csv.writeCsvHeader(); source.store("csv", csv); }) .onSourceEnd(source -> { final CsvWriter csv = source.retrieve("csv"); csv.close(); System.out.printf("Processed %d / %d products%n", source.productCount(), source.productGlobalCount()); }) .stream() .forEach(rec -> { final OnixProduct product = rec.product; final CsvWriter csv = rec.source.retrieve("csv"); try { MyProduct mp = JonixUnifier.unifyProduct(product, MyUnifier.unifier); csv.writeCsvLine(mp.toCsvColumns()); } catch (Exception e) { // e.printStackTrace(); // System.err.println(JonixJson.toJson(product)); System.err.printf("ERROR in #REF [%s]: %s%n", recordReferenceOf(product), e.getMessage()); // don't re-throw, don't break source, just continue to the next product.. } if (rec.source.productCount() == 50) { rec.breakStream(); } }); } ``` ```java public static String recordReferenceOf(OnixProduct product) { final String ref; if (product.onixVersion() == OnixVersion.ONIX2) { ref = Jonix.toProduct2(product).recordReference().value; } else if (product.onixVersion() == OnixVersion.ONIX3) { ref = Jonix.toProduct3(product).recordReference().value; } else { throw new RuntimeException("Unexpected type: " + product.getClass().getName()); } return (ref == null) ? "N/A" : ref; } ``` -------------------------------- ### Jonix Facade Class Initialization Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates the four different methods for initializing the Jonix facade class. These methods cover various scenarios for setting up the core Jonix processing engine. ```java JonixFacade facade = new JonixFacade(); JonixFacade facade = new JonixFacade(config); JonixFacade facade = JonixFacade.create(); JonixFacade facade = JonixFacade.create(config); ``` -------------------------------- ### Process Multiple ONIX Files Recursively Source: https://github.com/zach-m/jonix/blob/master/_autodocs/README.md This snippet shows how to process multiple ONIX files from a folder, including subdirectories, using a glob pattern. It also includes an example of logging when a source file starts processing. ```java Jonix.source(new File("folder"), "*.xml", true) // recursive glob .onSourceStart(src -> System.out.println("Processing " + src.sourceName())) .streamUnified() .forEach(record -> { // Process record }); ``` -------------------------------- ### Configure Per-Source Processing Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-configuration.md Utilize `onSourceStart` and `onSourceEnd` to manage source-specific state and actions, such as creating and closing per-source output files. This pattern enables accurate product counting for each source. ```java Map<String, CsvWriter> csvWriters = new HashMap<>(); Jonix.source(file1) .source(file2) .source(file3) .onSourceStart(src -> { String filename = src.sourceName(); CsvWriter csv = new CsvWriter(filename + ".csv"); src.store("csv", csv); System.out.println("Processing " + filename); }) .onSourceEnd(src -> { CsvWriter csv = src.retrieve("csv"); csv.close(); System.out.printf("Completed %s with %d products%n", src.sourceName(), src.productCount()); }) .stream() .forEach(record -> { CsvWriter csv = record.source.retrieve("csv"); // Write record using source's CSV writer }); ``` -------------------------------- ### Get First Item or Empty Instance from ListOfOnixComposite Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Returns the first item or a safe, empty instance if the list is empty. Allows method chaining without null checks. ```java public C firstOrEmpty() ``` -------------------------------- ### Jonix Error Handling: Missing Required Fields Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Illustrates handling of missing required fields, a common edge case in data processing. This example shows how Jonix might manage such situations. ```java // Handling missing required fields if (record.getIdentifier() == null) { // Handle missing identifier } ``` -------------------------------- ### Jonix Error Handling: Safe Navigation Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides an example of safe navigation in Jonix error handling. This pattern helps prevent null pointer exceptions when accessing nested data. ```java String title = record.getTitles()?.get(0)?.getValue(); // Safe navigation example ``` -------------------------------- ### Process Unified Products from a Source Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Demonstrates how to stream unified product data from a Jonix source. Use this to iterate over individual product records and access their details. ```java Jonix.source(file) .streamUnified() .forEach(baseRecord -> { String ref = baseRecord.product.info.recordReference; JonixSource src = baseRecord.source; }); ``` -------------------------------- ### Fluent API for ONIX-3 Extraction Source: https://github.com/zach-m/jonix/blob/master/README.md Process a folder containing only ONIX-3 sources using Jonix's fluent API. This example demonstrates advanced extraction of titles, authors, and front cover image links, handling missing elements gracefully. ```java Jonix.source(new File("/path/to/all-onix3-folder"), "*.xml", false) .onSourceStart(src -> { // safeguard: we skip non-ONIX-3 files if (src.onixVersion() != OnixVersion.ONIX3) { src.skipSource(); } }) .onSourceEnd(src -> { System.out.printf("<< Processed %d products from %s %n", src.productCount(), src.sourceName()); }) .stream() // iterate over the products contained in all ONIX sources .map(Jonix::toProduct3) .forEach(product -> { // take the requested information from the current product String ref = product.recordReference().value; String isbn13 = product.productIdentifiers() .find(ProductIdentifierTypes.ISBN_13) .map(pi -> pi.idValue().value) .orElse(null); String title = product.descriptiveDetail().titleDetails() .filter(td -> td.titleType().value == TitleTypes.Distinctive_title_book) .firstOrEmpty() .titleElements() .firstOrEmpty() .titleWithoutPrefix().value; List<String> authors = product.descriptiveDetail().contributors() .filter(c -> c.contributorRoles().values().contains(ContributorRoles.By_author)) .stream() .map(c -> c.personName().value().orElse( c.nameIdentifiers().find(NameIdentifierTypes.Proprietary) .flatMap(ni -> ni.idTypeName().value()) .orElse("N/A"))) .collect(Collectors.toList()); String frontCoverImageLink = product.collateralDetail().supportingResources() .filter(sr -> sr.resourceContentType().value == ResourceContentTypes.Front_cover) .firstOrEmpty() .resourceVersions() .filter(rv -> rv.resourceForm().value == ResourceForms.Downloadable_file) .first() .map(rv -> rv.resourceLinks().firstValueOrNull()) .orElse(null); System.out.println("ref = " + ref); System.out.println("isbn13 = " + isbn13); System.out.println("title = " + title); System.out.println("authors = " + authors); System.out.println("frontCoverImageLink = " + frontCoverImageLink); System.out.println("-----------------------------------------------------"); }); ``` -------------------------------- ### Creating a Custom Tabulation Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Shows how to create a custom Tabulation instance by adding specific field tabulators. ```java Tabulation<BaseProduct> custom = Tabulation.create() .add(BaseFieldTabulator.RECORD_ID) .add(BaseFieldTabulator.TITLE) .add(BaseFieldTabulator.PRICE); ``` -------------------------------- ### Jonix Configuration: Custom Unification Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates a pattern for custom unification in Jonix configuration. This enables the use of user-defined unification strategies. ```java // Pattern for custom unification JonixFacade facade = JonixFacade.create(config.unifier(myCustomUnifier)); ``` -------------------------------- ### Initialize JonixRecords from a List of Files Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Use this method to initialize JonixRecords from a list of File objects. All files in the list will be processed sequentially. ```Java public static JonixRecords source(List<File> files) ``` ```Java List<File> files = Arrays.asList( new File("file1.xml"), new File("file2.xml") ); Jonix.source(files) .stream() .forEach(record -> { // process record }); ``` -------------------------------- ### Get Contributor Display Names by Role Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Retrieve display names of contributors filtered by a specific role. Use this to get lists of authors, editors, etc. ```java public List<String> getDisplayNames(ContributorRoles role) ``` ```java List<String> authors = bp.contributors.getDisplayNames(ContributorRoles.By_author); List<String> editors = bp.contributors.getDisplayNames(ContributorRoles.Editor); ``` -------------------------------- ### JonixSource Class Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Query and control data sources, with support for storage and examples. ```APIDOC ## JonixSource Class ### Description Manages data sources, offering methods for querying data, controlling source behavior, and interacting with storage. Includes comprehensive examples. ### Methods - **Query**: 6 methods for retrieving data from the source. - **Control**: 2 methods for controlling the behavior of the data source. - **Storage**: Methods for interacting with data storage. ``` -------------------------------- ### JonixRecords Configuration Methods Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates three methods for configuring JonixRecords. Configuration allows customization of how records are managed and processed. ```java records.configure(config); records.setOption(key, value); records.loadConfig(path); ``` -------------------------------- ### Filter Contributors by Role Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Example of filtering a list of contributors to find only authors using the filter method. ```java List<Contributor> authors = product.contributors() .filter(c -> c.contributorRoles().values() .contains(ContributorRoles.By_author)); ``` -------------------------------- ### Get ONIX Version from JonixSource Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Returns the detected ONIX version (ONIX2 or ONIX3) for the current source. ```java public OnixVersion onixVersion() ``` -------------------------------- ### Get All Codelist Values Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Returns the list of all codelist values contained within this collection. This is an alias for the list itself. ```java public List<V> values() ``` -------------------------------- ### Get Item Class of ListOfOnixComposite Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Returns the class type of items in this list. Used for type introspection. ```java public Class<C> itemClass() ``` -------------------------------- ### Efficient BaseProduct Unification with Streaming Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-configuration.md Shows how Jonix's streamUnified() provides an efficient way to process unified product views with minimal memory overhead per product, as memory is released after processing. ```java // Efficient - minimal memory per product Jonix.source(file) .streamUnified() .forEach(rec -> { // rec.product is a unified view // Memory released after forEach completes }); ``` -------------------------------- ### source(List<File> files) Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Initializes a JonixRecords object from a list of ONIX files. This method allows for sequential processing of multiple ONIX files. ```APIDOC ## source(List<File> files) ### Description Initializes a JonixRecords from a list of ONIX files. All files are processed sequentially. ### Method ```java public static JonixRecords source(List<File> files) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | files | List<File> | Yes | Non-null list of files containing ONIX content | ### Returns `JonixRecords` — object for iterating over ONIX records in all files ### Request Example ```java List<File> files = Arrays.asList( new File("file1.xml"), new File("file2.xml") ); Jonix.source(files) .stream() .forEach(record -> { // process record }); ``` ``` -------------------------------- ### Filter ONIX Files by Version Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-configuration.md Use `onSourceStart` to skip files that do not match a specific ONIX version, such as ONIX3. ```java Jonix.source(mixed_files) .onSourceStart(src -> { if (src.onixVersion() != OnixVersion.ONIX3) { src.skipSource(); // Skip non-ONIX3 files } }) .stream() .map(Jonix::toProduct3) // Safe: all records are ONIX3 .forEach(product -> { // ONIX3-specific processing }); ``` -------------------------------- ### Get ONIX Release Version Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Retrieves the specific ONIX release version string, such as '3.1.3', for the current source. ```java public String onixRelease() ``` -------------------------------- ### Initialize JonixRecords by Scanning a Folder Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Use this method to initialize JonixRecords by scanning a specified folder for ONIX files matching a glob pattern. You can choose to scan recursively through subfolders. ```Java public static JonixRecords source(File folder, String glob, boolean recursive) ``` ```Java Jonix.source(new File("/onix-data"), "*.xml", true) .stream() .forEach(record -> { // process record }); ``` -------------------------------- ### Jonix Tabulation API Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Facilitates the tabulation and writing of Jonix data into delimited formats, with support for custom tabulators and examples. ```APIDOC ## Jonix Tabulation API ### Description Provides tools for tabulating and exporting Jonix data into delimited formats. Supports custom tabulators and includes comprehensive usage scenarios. ### Class: Tabulation<P> - **Methods**: 4 methods for tabulation operations. ### Class: BaseTabulation - **Built-in Tabulators**: Provides access to built-in tabulator implementations. ### Class: JonixDelimitedWriter<P> - **Constructors**: 2 constructors for initializing the writer. - **Methods**: 4 methods for writing delimited data. - **Static Collector Method**: A static method for collecting data. ### Interface: FieldTabulator - **Methods**: 2 methods for defining field tabulation logic. ### Examples - **Tabulation Examples**: 5 complete scenarios demonstrating tabulation usage. ``` -------------------------------- ### Jonix JSON API Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides functionality for serializing Jonix objects into JSON format, with support for Jackson implementations and examples. ```APIDOC ## Jonix JSON API ### Description Enables the serialization of Jonix data structures into JSON format. Supports various serialization methods and integrates with Jackson. ### Class: JonixJson - **toJson()**: 3 variants for general JSON serialization. - **productToJson()**: 2 variants for serializing product data. - **objectToJson()**: Method for serializing generic objects. ### Implementations - **Jackson**: Integrates with Jackson for JSON processing. ### Examples - **Serialization Examples**: 6 examples demonstrating JSON serialization. ``` -------------------------------- ### source(File folder, String glob, boolean recursive) Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Initializes a JonixRecords by scanning a folder for ONIX files matching a glob pattern. This method supports recursive scanning of subfolders. ```APIDOC ## source(File folder, String glob, boolean recursive) ### Description Initializes a JonixRecords by scanning a folder for ONIX files matching a glob pattern. ### Method ```java public static JonixRecords source(File folder, String glob, boolean recursive) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | folder | File | Yes | Parent folder to scan for files | | glob | String | Yes | Glob pattern (e.g., "*.xml", "onix*.xml") | | recursive | boolean | Yes | Whether to scan subfolders recursively | ### Returns `JonixRecords` — object for iterating over ONIX records in matching files ### Request Example ```java Jonix.source(new File("/onix-data"), "*.xml", true) .stream() .forEach(record -> { // process record }); ``` ``` -------------------------------- ### Get First Item from ListOfOnixComposite Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Returns an Optional containing the first item in the list, if present. Useful for safe access. ```java public Optional<C> first() ``` -------------------------------- ### Initialize JonixRecords from a File Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Use this method to initialize JonixRecords directly from a single File object containing ONIX XML content. ```Java public static JonixRecords source(File file) ``` ```Java Jonix.source(new File("/path/to/onix.xml")) .stream() .forEach(record -> { // process record }); ``` -------------------------------- ### Get Global Product Count Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Returns the total number of ONIX products processed across all sources handled by the Jonix processor. ```java public int productGlobalCount() ``` -------------------------------- ### Iterating Through Base Prices Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Demonstrates how to loop through a collection of BasePrice objects and print their type, amount, and currency code. This is useful for displaying or processing pricing information. ```java for (BasePrice price : prices) { System.out.printf("%s %s %s%n", price.priceType, price.priceAmountAsStr, price.currencyCode); } ``` -------------------------------- ### Jonix Configuration: Version-Specific Branching Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Illustrates a pattern for version-specific branching in Jonix configuration. This allows for tailored processing based on ONIX version. ```java // Pattern for version-specific branching JonixFacade facade = JonixFacade.create(config.branchOnVersion("3.0")); ``` -------------------------------- ### Get JonixSource Name Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Retrieves a descriptive name or label for the ONIX source, which is either an absolute file path or a stream identifier. ```java public String sourceName() ``` -------------------------------- ### Jonix XML API Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides utilities for parsing XML data and integrating with Jonix, including chunking, listeners, and direct usage examples. ```APIDOC ## Jonix XML API ### Description Offers utilities for parsing and processing XML data within the Jonix ecosystem. Includes features for XML chunking, event listening, and direct integration examples. ### Class: XmlChunker - **Static parse()**: A static method for parsing XML. - **Listener Interface**: An interface with 2 methods for handling XML parsing events. ### Class: XmlChunkerContext - **Methods**: 2 methods for managing the XML chunking context. ### Class: XmlUtil - **Utility Methods**: Provides various utility methods for XML processing. ### Examples - **Direct Usage Examples**: 3 examples demonstrating direct usage of the XML API. - **XML Example**: An example illustrating depth level explanation. ``` -------------------------------- ### skipSource() Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Skips the current source and moves to the next one. Call this in onSourceStart event handler. ```APIDOC ## skipSource() ### Description Skips the current source and moves to the next one. Call this in onSourceStart event handler. ### Method ```java public void skipSource() ``` ### Usage ```java records.onSourceStart(src -> { if (src.onixVersion() != OnixVersion.ONIX3) { src.skipSource(); } }); ``` ``` -------------------------------- ### JonixRecord Stream Control Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Provides examples for controlling the stream of a JonixRecord. These methods allow for pausing or resuming data processing for a specific record. ```java record.pauseStream(); record.resumeStream(); ``` -------------------------------- ### Using OnixCodelist.pair() Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Demonstrates how to use the `pair()` method of the `OnixCodelist` interface to obtain a `Pair` object containing both the code and description of a codelist value. ```java OnixCodelist.Pair p = TitleTypes.Distinctive_title_book.pair(); System.out.println(p.code); // "01" System.out.println(p.description); // "Distinctive title..." ``` -------------------------------- ### Get Product Count in JonixSource Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Returns the number of ONIX products that have been processed from the current source so far. This can be used in source end event handlers. ```java public int productCount() ``` ```java source.onSourceEnd(src -> { System.out.println("Processed " + src.productCount() + " products"); }); ``` -------------------------------- ### scanHeaders() Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Scans ONIX source files and fires onSourceStart events for headers only, without processing products. This is useful for header inspection before full processing. ```APIDOC ## scanHeaders() ### Description Scans ONIX source files and fires onSourceStart events for headers only, without processing products. This is useful for header inspection before full processing. ### Method ```java public void scanHeaders() ``` ### Usage ```java Jonix.source(new File("onix.xml")) .onSourceStart(src -> { src.header().map(Jonix::toBaseHeader) .ifPresent(h -> System.out.println("Sender: " + h.senderName)); }) .scanHeaders(); ``` ``` -------------------------------- ### onSourceStart(OnSourceEvent handler) Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Registers an event handler that is fired when processing of a new ONIX source begins, after the Header is read. The handler receives details about the source. ```APIDOC ## onSourceStart(OnSourceEvent handler) ### Description Registers an event handler that is fired when processing of a new ONIX source begins, after the Header is read. The handler receives details about the source. ### Method ```java public JonixRecords onSourceStart(JonixRecords.OnSourceEvent handler) ``` ### Parameters #### Path Parameters - **handler** (OnSourceEvent) - Required - Callback to invoke at source start ### Callback Parameter - **jonixSource** (JonixSource) - Provides source details. ### Response - **this** (JonixRecords) - Returns `this` for method chaining. ### Usage ```java records.onSourceStart(src -> { System.out.printf("Processing %s (ONIX %s)%n", src.sourceName(), src.onixVersion()); src.header().ifPresent(h -> { System.out.println("Sent from: " + Jonix.toBaseHeader(h).senderName); }); }); ``` ``` -------------------------------- ### Handling Missing ONIX Release Version Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-error-handling.md Demonstrates how to safely retrieve the ONIX release version from a source, which might be null if not explicitly specified in the header. Includes a check for a null value. ```java String release = source.onixRelease(); // May be null if not specified in header if (release == null) { System.out.println("Release not specified"); } ``` -------------------------------- ### Jonix Error Handling: Common Mistake Correction 1 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Presents a common mistake in Jonix usage and its correction. This example focuses on a specific pitfall and its resolution. ```java // Common mistake 1: Incorrectly assuming non-null // Correction: Always check for null or use safe navigation ``` -------------------------------- ### Get Tabulation Headers Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Retrieves the list of column headers generated from all added FieldTabulators. This is useful for creating CSV headers or defining database table schemas. ```java public List<String> header() ``` -------------------------------- ### Direct Writer Usage for Product Export Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Demonstrates direct usage of JonixDelimitedWriter to write products to a file. Handles potential exceptions during writing. ```java try (JonixDelimitedWriter<BaseProduct> writer = new JonixDelimitedWriter<>(outputFile, ',', tabulation)) { Jonix.source(new File("onix.xml")) .streamUnified() .map(rec -> rec.product) .forEach(product -> { try { writer.writeProduct(product); } catch (Exception e) { System.err.println("Error writing product: " + e.getMessage()); } }); } // writer closes automatically ``` -------------------------------- ### Multi-Source Export with Tracking Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-tabulation-api.md Exports data from multiple XML sources into a single CSV file. Includes callbacks to track the start and end of processing for each source. ```java File outputFile = new File("all_products.csv"); Jonix.source(new File("source1.xml")) .source(new File("source2.xml")) .onSourceStart(src -> { System.out.println("Processing " + src.sourceName()); }) .onSourceEnd(src -> { System.out.printf("Processed %d products from %s%n", src.productCount(), src.sourceName()); }) .streamUnified() .collect(toDelimitedFile(outputFile, ',', BaseTabulation.ALL)); ``` -------------------------------- ### Jonix Error Handling: Common Mistake Correction 3 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Presents a third common mistake and its correction. This example might focus on performance or resource management issues. ```java // Common mistake 3: Excessive object creation in loops // Correction: Reuse objects or use builders where appropriate ``` -------------------------------- ### Jonix Error Handling: Common Mistake Correction 2 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Presents a second common mistake and its correction. This example addresses another frequent issue encountered by users. ```java // Common mistake 2: Ignoring empty collections // Correction: Use isEmpty() checks before iteration ``` -------------------------------- ### Jonix Facade Class Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt The Jonix facade class provides entry points for source initialization, type casting, and unification operations. ```APIDOC ## Jonix Facade Class ### Description Provides a high-level interface for interacting with Jonix functionalities, including initializing data sources, performing type casting, and unifying data. ### Methods - **Source Initialization**: 4 methods available for setting up data sources. - **Type Casting**: 6 methods for converting data between different types. - **Unification**: 3 methods for unifying disparate data sources or formats. ``` -------------------------------- ### Jonix Configuration: Version Filtering Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates a pattern for version filtering in Jonix configuration. This allows selective processing of records based on their ONIX version. ```java // Pattern for version filtering JonixFacade facade = JonixFacade.create(config.filterByVersion("2.1")); ``` -------------------------------- ### Find Product ID by Type Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Retrieves a product identifier by its specified type. Use this method to get specific IDs like ISBN-13 or ISBN-10 from the product information. ```java public String findProductId(ProductIdentifierTypes type) ``` ```java String isbn13 = bp.info.findProductId(ProductIdentifierTypes.ISBN_13); String isbn10 = bp.info.findProductId(ProductIdentifierTypes.ISBN_10); ``` -------------------------------- ### Jonix Error Handling: Common Mistake Correction 4 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Presents a fourth common mistake and its correction. This example could address issues related to concurrency or thread safety. ```java // Common mistake 4: Modifying shared state without synchronization // Correction: Use concurrent collections or proper locking mechanisms ``` -------------------------------- ### Jonix Error Handling: Null Values in Elements Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Shows how to handle null values within elements, a frequent source of errors. This example focuses on robust data access. ```java // Handling null values in elements String publisher = record.getPublisher() != null ? record.getPublisher().getName() : "N/A"; ``` -------------------------------- ### Batch Serialize Products to JSON Lines File Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-json-api.md Serializes multiple ONIX product records from a file into a JSON Lines (jsonl) file. Each product is written as a separate JSON object on a new line. This is efficient for large datasets. ```java PrintWriter writer = new PrintWriter(new FileWriter("products.jsonl")); Jonix.source(new File("onix.xml")) .streamUnified() .forEach(rec -> { String json = JonixJson.toJson(rec.product, false); writer.println(json); }); writer.close(); ``` -------------------------------- ### Safe Access to Collection Elements Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-error-handling.md Do not assume collections have methods like `get(0)` which can throw exceptions if the collection is empty. Use methods like `firstOrEmpty()` for safe access. ```java // WRONG - List methods always safe but... product.titles.get(0) // Throws if empty // CORRECT product.titles.firstOrEmpty() // Returns empty composite if no items ``` -------------------------------- ### Jonix Error Handling: Common Mistake Correction 5 Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Presents a fifth common mistake and its correction. This example might cover type conversion pitfalls or unexpected data formats. ```java // Common mistake 5: Incorrect type conversions // Correction: Use explicit and safe conversion methods provided by Jonix ``` -------------------------------- ### XmlChunkerContext Constructor Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-xml-api.md Initializes the XmlChunkerContext with an input stream, encoding, and target depth. Use this to set up the XML parsing context. ```java public XmlChunkerContext(InputStream is, String encoding, int targetDepth) throws XMLStreamException; ``` -------------------------------- ### toBaseRecord(JonixRecord jonixRecord) Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Converts a low-level JonixRecord to a unified BaseRecord containing version-agnostic data. This includes both the product information and its source. ```APIDOC ## toBaseRecord(JonixRecord jonixRecord) ### Description Converts a low-level JonixRecord to a unified BaseRecord containing version-agnostic data. ### Method ```java public static BaseRecord toBaseRecord(JonixRecord jonixRecord) ``` ### Parameters #### Path Parameters - **jonixRecord** (JonixRecord) - Yes - Record to unify ### Returns `BaseRecord` — unified record with BaseProduct and source information ### Usage: ```java BaseRecord baseRecord = Jonix.toBaseRecord(record); BaseProduct product = baseRecord.product; ``` ``` -------------------------------- ### Product String Representation Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-unification-api.md Returns a formatted string representation of the product, including its titles and product identifiers. This is useful for debugging or displaying a summary. ```java @Override public String toString() ``` -------------------------------- ### OnixCodelist Interface Definition Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-common-types.md Represents an ONIX Codelist enumeration value, providing methods to get the code and its human-readable description. It also offers a utility method to return these as a Pair object. ```java public interface OnixCodelist { String getCode(); String getDescription(); default Pair pair() { return new Pair(getCode(), getDescription()); } class Pair { public final String code; public final String description; public Pair(String code, String description) { this.code = code; this.description = description; } } } ``` -------------------------------- ### source(File file) Source: https://github.com/zach-m/jonix/blob/master/_autodocs/jonix-core-api.md Initializes a JonixRecords object from a single ONIX file. This is a convenient method for processing a single ONIX XML file directly from the file system. ```APIDOC ## source(File file) ### Description Initializes a JonixRecords from a single ONIX file. ### Method ```java public static JonixRecords source(File file) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | file | File | Yes | File containing ONIX XML content | ### Returns `JonixRecords` — object for iterating over ONIX records ### Request Example ```java Jonix.source(new File("/path/to/onix.xml")) .stream() .forEach(record -> { // process record }); ``` ``` -------------------------------- ### Custom Unifier Implementation Pattern Source: https://github.com/zach-m/jonix/blob/master/_autodocs/COMPLETION_REPORT.txt Demonstrates a pattern for implementing a custom unifier. This pattern shows how to create concrete classes that adhere to the custom unifier interface. ```java class MyUnifier implements CustomUnifier<MyData> { @Override public MyData unify(MyData data1, MyData data2) { // Custom unification logic here return unifiedData; } } ```