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

com.microsoft.azure.toolkit.lib.common.utils.aspect.ExpressionUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */

package com.microsoft.azure.toolkit.lib.common.utils.aspect;

import com.azure.resourcemanager.resources.fluentcore.arm.ResourceUtils;
import com.google.common.collect.ImmutableMap;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.codehaus.groovy.runtime.MethodClosure;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Slf4j
public class ExpressionUtils {
    private static final ImmutableMap valueMap = ImmutableMap.of("true", true, "false", false);
    private static final SimpleTemplateEngine engine = new SimpleTemplateEngine();
    private static final String INVALID_TEMPLATE = "error occurs when evaluate template(%s) with bindings(%s)";

    public static boolean evaluate(@Nonnull final String expression, @Nonnull final MethodInvocation invocation, boolean defaultVal) {
        final String result = interpret(expression, invocation);
        return Boolean.TRUE.equals(valueMap.getOrDefault(Optional.ofNullable(result).map(String::toLowerCase).orElse(null), defaultVal));
    }

    public static String interpret(@Nonnull final String expression, @Nonnull final MethodInvocation invocation) {
        return render(String.format("${%s}", expression), invocation);
    }

    @Nullable
    public static Object evaluate(@Nonnull final String expression, @Nonnull final MethodInvocation invocation) {
        if (StringUtils.isBlank(expression)) { // no groovy expression, just return
            return null;
        }
        final Map bindings = initBindings(invocation);
        final String fixed = expression.replaceAll("(\\W?)this(\\.)", "$1_this_$2"); // resolve `this`
        try {
            final GroovyShell shell = new GroovyShell(ExpressionUtils.class.getClassLoader(), new Binding(bindings));
            return shell.evaluate(fixed);
        } catch (final Throwable e) { // swallow all exceptions during render
            log.warn(String.format(INVALID_TEMPLATE, expression, bindings), e);
        }
        return null;
    }

    public static String render(@Nullable final String template, @Nonnull final MethodInvocation invocation) {
        if (StringUtils.isBlank(template) || !template.contains("$")) { // no groovy expression, just return
            return template;
        }
        final Map bindings = initBindings(invocation);
        final String fixed = template.replaceAll("(\\W)this(\\.)", "$1_this_$2"); // resolve `this`
        try {
            final Template tpl = engine.createTemplate(fixed);
            return tpl.make(bindings).toString();
        } catch (final Throwable e) { // swallow all exceptions during render
            log.warn(String.format(INVALID_TEMPLATE, template, bindings), e);
        }
        return template;
    }

    @Nonnull
    private static Map initBindings(@Nonnull final MethodInvocation invocation) {
        final List> args = invocation.getArgs();
        final Map bindings = new HashMap<>();
        for (final Triple arg : args) {
            bindings.put(arg.getLeft(), arg.getRight());
        }
        bindings.put("_this_", invocation.getInstance());
        bindPredefinedFunctions(bindings);
        return bindings;
    }

    private static void bindPredefinedFunctions(@Nonnull Map bindings) {
        bindings.put("nameFromResourceId", new MethodClosure(ResourceUtils.class, "nameFromResourceId"));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy