Unidor
El ensamblador es responsable de unir componentes a granel.
Implementación predeterminada de Joiner (InsertionPointJoiner) utiliza puntos de inserción detectados por Buscador de Puntos de Inserción para coser componentes a granel.
El unidor tiene una dependencia del almacén de componentes, el cual espera que esté poblado con componentes que, al combinarse con una jerarquía de componentes para definir las relaciones de los componentes, pueden ser fusionados para formar un documento válido que puede ser ingerido por otro sistema.
Espacios de nombres
Si su bulked Los componentes utilizan espacios de nombres. Puede haber un caso en el que necesite que los elementos secundarios coincidan con el prefijo del espacio de nombres del padre. En estos casos, puede agregar una configuración adicional (configurations[0].component-hierarchy.namespace-prefix) para hacerlo en la configuración del padre, y cualquier hijo tendrá este prefijo aplicado.
Ejemplo:
ipf.bulker {
configurations = [
{
name = "IDF"
file-name-prefix = "idf-"
file-path = "/tmp/bulks"
component-hierarchy {
insertion-point-finder = "xml"
marker = "MPEDDIdfBlkDirDeb"
namespace-prefix = "S2SDDIdf"
children = [
{
marker = "FIToFICstmrDrctDbt"
}
]
}
}
]
}
Ejemplo de salida xml sería:
<S2SDDIdf:FIToFICstmrDrctDbt xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.003.001.08">...</FIToFICstmrDrctDbt>
Ejemplo de Uso
Este ejemplo de uso sigue el mismo escenario utilizado para demostrar el Divisor XML pero al revés. Poblaremos un almacén de componentes, crearemos una jerarquía de componentes para determinar cómo deben unirse los componentes y, finalmente, proporcionaremos un flujo de salida para que el contenido unido pueda ser transmitido a donde sea necesario.
Este ejemplo une únicamente un puñado de componentes con fines demostrativos, pero esto puede escalar a muchos más componentes. A continuación se presenta el contenido de cada uno de los componentes que se conserva dentro del almacén de componentes.
example-library-component.xml
<library>
<name>Library of Alexandria</name>
</library>
example-book-component-1.xml
<book>
<author>Martin, Robert</author>
<title>Clean Code</title>
</book>
example-book-component-2.xml
<book>
<author>Bloch, Joshua</author>
<title>Effective Java</title>
</book>
example-chapter-component-1.xml
<chapter>
<name>Clean Code</name>
<startPage>1</startPage>
</chapter>
example-chapter-component-2.xml
<chapter>
<name>Meaningful Names</name>
<startPage>17</startPage>
</chapter>
example-chapter-component-3.xml
<chapter>
<name>Introduction</name>
<startPage>1</startPage>
</chapter>
example-chapter-component-4.xml
<chapter>
<name>Creating and Destroying Objects</name>
<startPage>5</startPage>
</chapter>
Let’s write an example program to first load the components into the component store and then process them using the XML Joiner.
ComponentStore<List<InsertionPoint>> componentStore = new InMemoryComponentStore<>();
// Create component hierarchy
var rootNode = Node.root("library", "xml");
var bookNode = rootNode.createChild("book", Collections.emptyList());
var chapterNode = bookNode.createChild("chapter", Collections.emptyList());
// Populate the component store
BulkId bulkId = BulkId.random();
var root = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.of(bulkId.getValue()))
.index(0L).marker("library")
.content(readResourceFile("example-root-component.xml"))
.custom(List.of(new InsertionPoint(bookNode, 49))).build();
var book1 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(root.getId())
.index(1L).marker("library.book")
.content(readResourceFile("example-book-component-1.xml"))
.custom(List.of(new InsertionPoint(chapterNode, 73))).build();
var book2 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(root.getId())
.index(2L).marker("library.book")
.content(readResourceFile("example-book-component-2.xml"))
.custom(List.of(new InsertionPoint(chapterNode, 76))).build();
var chapter1 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(book1.getId())
.index(3L).marker("library.book.chapter")
.content(readResourceFile("example-chapter-component-1.xml"))
.custom(Collections.emptyList()).build();
var chapter2 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(book1.getId())
.index(4L).marker("library.book.chapter")
.content(readResourceFile("example-chapter-component-2.xml"))
.custom(Collections.emptyList()).build();
var chapter3 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(book2.getId())
.index(5L).marker("library.book.chapter")
.content(readResourceFile("example-chapter-component-3.xml"))
.custom(Collections.emptyList()).build();
var chapter4 = Component.<List<InsertionPoint>>builder()
.bulkId(bulkId).id(ComponentId.random()).parentId(book2.getId())
.index(6L).marker("library.book.chapter")
.content(readResourceFile("example-chapter-component-4.xml"))
.custom(Collections.emptyList()).build();
Mono.zip(
Mono.fromCompletionStage(componentStore.save(root)),
Mono.fromCompletionStage(componentStore.save(book1)),
Mono.fromCompletionStage(componentStore.save(book2)),
Mono.fromCompletionStage(componentStore.save(chapter1)),
Mono.fromCompletionStage(componentStore.save(chapter2)),
Mono.fromCompletionStage(componentStore.save(chapter3)),
Mono.fromCompletionStage(componentStore.save(chapter4))
).block();
Joiner joiner = new XmlJoiner(componentStore);
OutputStream stream = new ByteArrayOutputStream();
var rootId = BulkComponentId.of(root.getId().getValue());
Mono.fromCompletionStage(joiner.join(rootId, rootNode, stream)).block(Duration.ofSeconds(5));
String output = stream.toString();
System.out.println(output);
Running this code should print out the following to the console. The whitespace formatting may look a bit different due to the way the components are appended to the stream, but the content should effectively be the same.
output
<library>
<name>Library of Alexandria</name>
<book>
<author>Martin, Robert</author>
<title>Clean Code</title>
<chapter>
<name>Clean Code</name>
<startPage>1</startPage>
</chapter>
<chapter>
<name>Meaningful Names</name>
<startPage>17</startPage>
</chapter>
</book>
<book>
<author>Bloch, Joshua</author>
<title>Effective Java</title>
<chapter>
<name>Introduction</name>
<startPage>1</startPage>
</chapter>
<chapter>
<name>Creating and Destroying Objects</name>
<startPage>5</startPage>
</chapter>
</book>
</library>