001/**
002 * Copyright (C) 2006-2025 Talend Inc. - www.talend.com
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.talend.sdk.component.runtime.manager.reflect.parameterenricher;
017
018import static java.util.Collections.emptyMap;
019import static java.util.stream.Collectors.joining;
020import static java.util.stream.Collectors.toMap;
021
022import java.lang.annotation.Annotation;
023import java.lang.reflect.InvocationTargetException;
024import java.lang.reflect.Method;
025import java.lang.reflect.Type;
026import java.util.HashMap;
027import java.util.Map;
028import java.util.function.Predicate;
029import java.util.stream.Stream;
030
031import org.talend.sdk.component.api.configuration.condition.ActiveIf;
032import org.talend.sdk.component.api.configuration.condition.ActiveIfs;
033import org.talend.sdk.component.api.configuration.condition.meta.Condition;
034
035public class ConditionParameterEnricher extends BaseParameterEnricher {
036
037    private static final String META_PREFIX = "tcomp::condition::";
038
039    @Override
040    public Map<String, String> onParameterAnnotation(final String parameterName, final Type parameterType,
041            final Annotation annotation) {
042        final Condition condition = annotation.annotationType().getAnnotation(Condition.class);
043        if (condition != null) {
044            final String type = condition.value();
045            if (ActiveIfs.class.isInstance(annotation)) {
046                final ActiveIfs activeIfs = ActiveIfs.class.cast(annotation);
047                final Map<String, String> metas = Stream
048                        .of(activeIfs.value())
049                        .map(ai -> onParameterAnnotation(parameterName, parameterType, ai))
050                        .collect(HashMap::new, (map, entry) -> {
051                            final String suffix = "::" + (map.size() / 4);
052                            map
053                                    .putAll(entry
054                                            .entrySet()
055                                            .stream()
056                                            .collect(toMap(e -> e.getKey() + suffix, Map.Entry::getValue)));
057                        }, HashMap::putAll);
058                metas.putAll(toMeta(annotation, type, m -> !"value".equals(m.getName())));
059                return metas;
060            }
061            return toMeta(annotation, type, m -> true);
062
063        }
064        return emptyMap();
065    }
066
067    private Map<String, String> toMeta(final Annotation annotation, final String type, final Predicate<Method> filter) {
068        return Stream
069                .of(annotation.annotationType().getMethods())
070                .filter(m -> !m.getName().endsWith("evaluationStrategyOptions"))
071                .filter(m -> m.getDeclaringClass() == annotation.annotationType())
072                .filter(filter)
073                .collect(toMap(m -> META_PREFIX + type + "::" + m.getName(), m -> {
074                    try {
075                        final Object invoke = m.invoke(annotation);
076                        if (String[].class.isInstance(invoke)) {
077                            return Stream.of(String[].class.cast(invoke)).collect(joining(","));
078                        }
079                        if (ActiveIf.class == m.getDeclaringClass() && "evaluationStrategy".equals(m.getName())) {
080                            final ActiveIf.EvaluationStrategyOption[] options =
081                                    ActiveIf.class.cast(annotation).evaluationStrategyOptions();
082                            if (options.length > 0) {
083                                return String.valueOf(invoke) + Stream
084                                        .of(options)
085                                        .map(o -> o.name() + '=' + o.value())
086                                        .collect(joining(",", "(", ")"));
087                            }
088                        }
089                        return String.valueOf(invoke);
090                    } catch (final InvocationTargetException | IllegalAccessException e) {
091                        throw new IllegalStateException(e);
092                    }
093                }));
094    }
095}