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

com.powsybl.iidm.network.scripting.GroovyScriptPostProcessor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2017, RTE (http://www.rte-france.com)
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * SPDX-License-Identifier: MPL-2.0
 */
package com.powsybl.iidm.network.scripting;

import com.google.auto.service.AutoService;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.config.PlatformConfig;
import com.powsybl.computation.ComputationManager;
import com.powsybl.iidm.network.ImportPostProcessor;
import com.powsybl.iidm.network.Network;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.transform.ThreadInterrupt;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

/**
 * @author Mathieu Bague {@literal }
 */
@AutoService(ImportPostProcessor.class)
public class GroovyScriptPostProcessor implements ImportPostProcessor {

    public static final String NAME = "groovyScript";

    public static final String DEFAULT_SCRIPT_NAME = "import-post-processor.groovy";

    private static final Logger LOGGER = LoggerFactory.getLogger(GroovyScriptPostProcessor.class);

    private final Path script;

    public GroovyScriptPostProcessor() {
        this(PlatformConfig.defaultConfig());
    }

    public GroovyScriptPostProcessor(PlatformConfig platformConfig) {
        this(getConfiguredScript(platformConfig));
    }

    public GroovyScriptPostProcessor(Path script) {
        this.script = Objects.requireNonNull(script);
    }

    private static Path getConfiguredScript(PlatformConfig platformConfig) {
        Objects.requireNonNull(platformConfig);
        return platformConfig.getOptionalModuleConfig("groovy-post-processor")
                .flatMap(config -> config.getOptionalPathProperty("script"))
                .or(() -> platformConfig.getConfigDir().map(dir -> dir.resolve(DEFAULT_SCRIPT_NAME)))
                .orElseThrow(() -> new PowsyblException("No script path nor configuration directory defined in platform config"));
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public void process(Network network, ComputationManager computationManager) throws Exception {
        if (Files.exists(script)) {
            LOGGER.debug("Execute groovy post processor {}", script);
            try (Reader reader = Files.newBufferedReader(script, StandardCharsets.UTF_8)) {
                CompilerConfiguration conf = new CompilerConfiguration();
                // Add a check on thread interruption in every loop (for, while) in the script
                conf.addCompilationCustomizers(new ASTTransformationCustomizer(ThreadInterrupt.class));

                Binding binding = new Binding();
                binding.setVariable("network", network);
                binding.setVariable("computationManager", computationManager);

                GroovyShell shell = new GroovyShell(binding, conf);

                // Check for thread interruption right before beginning the evaluation
                if (Thread.currentThread().isInterrupted()) {
                    throw new InterruptedException("Execution Interrupted");
                }
                shell.evaluate(reader);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy