Data Format Conversions

Moving from one data format to another is one of the core features of Pogues. This transformations may be accomplished using XSL transformations, external API calls, a set of serializer or whatever future expectation may require. Transformations may be chained together as well as used separately.

To help will this, every transformation implementation will have to rely on a common interface, easing the process of chaining or swapping transformations all accross the application.

The Transformer Interface

Consequently, as soon as we need to implement a transformation we will implement the Transformer interface which defines a set of transform methods with different types of inputs and outputs.

package fr.insee.pogues.transforms;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

public interface Transformer {
    void transform(InputStream input, OutputStream output, Map<String, Object> params, String surveyName)
            throws Exception;

    String transform(InputStream input, Map<String, Object> params, String surveyName) throws Exception;

    String transform(String input, Map<String, Object> params, String surveyName) throws Exception;

}

The params Map can be used to pass parameters along the transformation process that can be used by transformers to produce their output.

The transform functional interface

To be able to use the Transformer interface methods using java 8 method references we define a Functional Interface which every Transformer method will conform to:

    @FunctionalInterface
    public interface Transform<I, O> {
        O apply(I i, Map<String, Object> params, String surveyName) throws Exception;
    }

The Pipeline class

The Pipeline class is where we can chain our transform methods together to set up a more complex transformation process.

For instance, visualization is accomplished using the Pipeline class and a the following transformer chain:

[Pogues JSON] -> [Pogues XML] -> [DDI] -> [XForm] -> [Form URI]

Here is what the code will look like:

class PipeSample{
    public String pipe(HttpServletRequest request){
        return pipeline
            .from(request.getInputStream())
            .map(jsonToXML::transform, params)
            .map(xmlToDDI::transform, params)
            .map(ddiToXForm::transform, params)
            .map(xformToUri::transform, params)
            .transform()
            .getBytes();
    }
}

Currently our very first implementation of the Pipeline class sticks to String inputs and String outputs.

Building a transformation chain begins with setting the input of the chain in the from method of the pipeline class (in the example we get our input from a request as a stream but input could be passed as well as a string argument). Then we can chain transformers using the map method of the Pipeline. Both the from and the map method return the Pipeline instance, allowing us to chain call fluently.

Once we chained our Transformers we can then trigger the transformation process by calling transform on the pipeline. We have to notice that no transformation will be applied until we call this method.

results matching ""

    No results matching ""