/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * 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.
 */
package io.gravitee.gateway.reactor.handler.context;

import io.gravitee.el.TemplateVariableProvider;
import io.gravitee.el.TemplateVariableScope;
import io.gravitee.el.annotations.TemplateVariable;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.ClassUtils;

/**
 * @author David BRASSELY (david.brassely at graviteesource.com)
 * @author GraviteeSource Team
 */
public abstract class TemplateVariableProviderFactory {

    private final Logger logger = LoggerFactory.getLogger(TemplateVariableProviderFactory.class);

    @Autowired
    private ApplicationContext applicationContext;

    public List<TemplateVariableProvider> getTemplateVariableProviders() {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        return loadFactories(classLoader)
            .stream()
            .map(
                name -> {
                    try {
                        Class<TemplateVariableProvider> instance = (Class<TemplateVariableProvider>) ClassUtils.forName(name, classLoader);
                        return applicationContext.getBean(instance);
                    } catch (ClassNotFoundException | NoSuchBeanDefinitionException e) {
                        logger.warn(e.getMessage());
                        return null;
                    }
                }
            )
            .filter(
                provider -> {
                    if (provider != null) {
                        TemplateVariable annotation = provider.getClass().getAnnotation(TemplateVariable.class);
                        return annotation != null && Arrays.asList(annotation.scopes()).contains(getTemplateVariableScope());
                    }
                    return false;
                }
            )
            .collect(Collectors.toList());
    }

    public Set<String> loadFactories(ClassLoader classLoader) {
        return new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(TemplateVariableProvider.class, classLoader));
    }

    public abstract TemplateVariableScope getTemplateVariableScope();
}

@@ -2202,10 +2202,181 @@
 ion 
-%7C 
+e) %7B%0A                        logger.warn(%22TemplateVariableProvider class not found : %7B%7D%22, e.getMessage());%0A                        return null;%0A                    %7D catch (
 NoSu
@@ -2441,27 +2441,71 @@
 ger.
-warn(e.getMessage()
+debug(%22No TemplateVariableProvider of type %7B%7D is defined%22, name
 );%0A 

fix irrelevant WARN message when a TemplateVariableProvider is not defined