All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.regnosys.testing.testpack.TestPackFunctionRunnerProviderImpl Maven / Gradle / Ivy

Go to download

Rune Testing is a java library that is utilised by Rosetta Code Generators and models expressed in the Rosetta DSL.

There is a newer version: 11.27.2
Show newest version
package com.regnosys.testing.testpack;

/*-
 * ===============
 * Rosetta Testing
 * ===============
 * Copyright (C) 2022 - 2024 REGnosys
 * ===============
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ===============
 */

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import com.google.inject.Injector;
import com.regnosys.rosetta.common.hashing.ReferenceConfig;
import com.regnosys.rosetta.common.serialisation.RosettaObjectMapper;
import com.regnosys.rosetta.common.transform.PipelineModel;
import com.regnosys.rosetta.common.validation.RosettaTypeValidator;
import com.rosetta.model.lib.RosettaModelObject;
import org.xml.sax.SAXException;

import javax.inject.Inject;
import javax.xml.XMLConstants;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Optional;
import java.util.function.Function;

import static com.regnosys.rosetta.common.transform.TestPackUtils.getObjectWriter;

public class TestPackFunctionRunnerProviderImpl implements TestPackFunctionRunnerProvider {

    protected static final ObjectMapper JSON_OBJECT_MAPPER = RosettaObjectMapper.getNewRosettaObjectMapper();
    protected final static ObjectWriter JSON_OBJECT_WRITER =
            JSON_OBJECT_MAPPER
                    .configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
                    .writerWithDefaultPrettyPrinter();

    @Inject
    RosettaTypeValidator typeValidator;
    @Inject
    ReferenceConfig referenceConfig;

    @Override
    public TestPackFunctionRunner create(PipelineModel.Transform transform, Injector injector) {
        Class inputType = toClass(transform.getInputType());
        Class functionType = toClass(transform.getFunction());
        return createTestPackFunctionRunner(functionType, inputType, injector, JSON_OBJECT_WRITER, null);
    }

    @Override
    public TestPackFunctionRunner create(PipelineModel.Transform transform, PipelineModel.Serialisation outputSerialisation, ImmutableMap, String> outputSchemaMap, Injector injector) {
        Class inputType = toClass(transform.getInputType());
        Class outputType = toClass(transform.getOutputType());
        // Output serialisation
        ObjectWriter outputObjectWriter = getObjectWriter(outputSerialisation).orElse(JSON_OBJECT_WRITER);
        // XSD validation
        Validator xsdValidator = getXsdValidator(outputType, outputSchemaMap);
        return createTestPackFunctionRunner(toClass(transform.getFunction()), inputType, injector, outputObjectWriter, xsdValidator);
    }

    private  TestPackFunctionRunner createTestPackFunctionRunner(Class functionType, Class inputType, Injector injector, ObjectWriter outputObjectWriter, Validator xsdValidator) {
        Function transformFunction = getTransformFunction(functionType, inputType, injector);
        return new TestPackFunctionRunnerImpl<>(transformFunction, inputType, typeValidator, referenceConfig, outputObjectWriter, xsdValidator);
    }

    private Class toClass(String name) {
        try {
            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
            if (contextClassLoader != null) {
                return (Class) contextClassLoader.loadClass(name);
            }
            return (Class) Class.forName(name);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private  Function getTransformFunction(Class functionType, Class inputType, Injector injector) {
        Object functionInstance = injector.getInstance(functionType);
        Method evaluateMethod;
        try {
            evaluateMethod = functionInstance.getClass().getMethod("evaluate", inputType);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(String.format("Evaluate method with input type %s not found", inputType.getName()), e);
        }
        return (resolvedInput) -> {
            try {
                return (RosettaModelObject) evaluateMethod.invoke(functionInstance, resolvedInput);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException("Failed to invoke evaluate method", e);
            }
        };
    }

    private Validator getXsdValidator(Class functionType, ImmutableMap, String> outputSchemaMap) {
        URL schemaUrl = Optional.ofNullable(outputSchemaMap.get(functionType))
                .map(r -> Resources.getResource(r))
                .orElse(null);
        if (schemaUrl == null) {
            return null;
        }
        try {
            SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            // required to process xml elements with an maxOccurs greater than 5000 (rather than unbounded)
            schemaFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
            Schema schema = schemaFactory.newSchema(schemaUrl);
            return schema.newValidator();
        } catch (SAXException e) {
            throw new RuntimeException(String.format("Failed to create schema validator for {}", schemaUrl), e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy