Skip to content

Reading Structures

StrutureReaderManager

The StructureReaderManager is the entry point for all structure read requests. It is the responsibility of the StructureReaderManager to find the appropriate reader based on the version and format of the structures message being read. The StructureReaderManager also supports post read processes, and automatic upgrades of SDMX-IM version for any deprecated structures from previous versions of the SDMX Information Model.

The ReadableDataLocation is the main input into the StructureReaderManager, as it provides the stream of information to convert into the sdmx-core object model.

The output is the SdmxBeans container.

The StructureReaderManager would typically be set up globally during the application startup phase, and registered with the SingletonStore

The StructureReaderManager delegates the read operation to a StructureReaderFactory. All StructureReaderFactory instances required for the application must first be registered with the sdmx-core framework via the FusionBeanStore; this must be done before the StructureReaderManager is invoked for the first time.

For convenience the sdmx-core framework provides automatic registration of StructureReaderFactory implementations in the IFusionModule.

Basic Read

A basic read requires any format Modules to be registered with the framework, these are automatically found by the StructureReaderManager.

Passing in the ReadableDataLocation will create the SdmxBeans output.

//Register the module(s) for the formats to be supported
SdmxJsonModule.register();  //register SDMX JSON readers and writers
SdmxMLModule.register();    //register SDMX-ML readers and writers

StructureReaderManager srm = new StructureReaderManagerImpl();
ReadableDataLocation rdl = new ReadableDataLocationTmp(file);
SdmxBean beans = srm.parseStructures(rdl);

Configuration

The StructureReaderManager has a global configuration that can be set up in the constructor. In addition individual parseStructures requests can be given a configuration which overrides the defaults.

There are two main concepts in the build process that can be configured or intercepted

  1. How a MaintainableMutableBean is converted into an SDMXBean (immutable)
  2. How a MaintainableBean is added to the SdmxBeans container

IImmutableBeanBuilder

The first interception point is the IImmutableBeanBuilder interface, the contract is to make a mutable bean immutable. The standard implementation simply calls the getImmutableInstance() method on the immutable bean

StandardImmutableBeanBuilder

@Override
public MaintainableBean build(MaintainableMutableBean mutable) {
  return mutable.getImmutableInstance();
}

The purpose of this interception point is to allow the client to override this behaviour, for example

DeferredImmutableBeanBuilder

There is the option to create a Deferred Bean on build, which offloads the object to the file system.

@Override
    public MaintainableBean build(MaintainableMutableBean mutable) {
        MaintainableBean maint = mutable.getImmutableInstance();
        if(maint.getDeferredDefinition() != null) {
            return maint.toDeferred();
        }
        return maint;
    }

ErrorHandlingIImmutableBeanBuilder

Alternatively, to handle errors during reading and allow files to be read without stopping if invalid content is found: The ErrorHandlingIImmutableBeanBuilder proxies another IImmutableBeanBuilder, enabling them to be chained.

@Override
public MaintainableBean build(MaintainableMutableBean mutable) {
    try {
        return proxy.build(mutable);
    } catch(Throwable th) {
        IURN<?> urn = URN.builder(mutable.getAgencyId(), mutable.getId(), mutable.getVersion()).structure(mutable.getStructureType()).build();

        IStructureValidationError err = new StructureValidationError(urn, Collections.singletonList(th.getMessage()));
        errorHandler.handleError(err);
        return null;
    }
}

IBeansBuilder

The IBeansBuilder interface provides control over how the bean is added to the SdmxBeans container. There are two implementations. The StandardBeanBuilder simply creates the immutable bean and adds it to the SdmxBeans container. The V3BeansBuilder upgrades any deprecated SDMX-IM classes into the SDMX v3.0 model before adding to the container.

Examples

Reading Deferred Beans

private SdmxBeans getStructures(String url) {
    IImmutableBeanBuilder immutableBeanBuilder = DeferredImmutableBeanBuilder.getInstance();
    IBeansBuilder builder = new StandardBeanBuilder(immutableBeanBuilder);
    StructureReaderManager srm = new StructureReaderManagerImpl(builder);
    try (ReadableDataLocation rdl = new ReadableDataLocationTmp(url) ){
        return srm.parseStructures(rdl);
    }
 }

Handle Errors on Read - upgrade SDMX-IM

private static SdmxBeans getStructures(String url) {
    IImmutableBeanBuilder proxy  = StandardImmutableBeanBuilder.INSTANCE;
    IStructureValidationErrorHandler errorHandler = new StructureValidationErrorHandler();
    IImmutableBeanBuilder errorBuilder = new ErrorHandlingIImmutableBeanBuilder(proxy, errorHandler);
    IBeansBuilder builder = new V3BeansBuilder(errorBuilder);

    StructureReaderManager srm = new StructureReaderManagerImpl(builder);
    try (ReadableDataLocation rdl = new ReadableDataLocationTmp(url) ){
        return srm.parseStructures(rdl);
    }
}