001/**
002 * Copyright (C) 2006-2024 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;
017
018import static java.util.Comparator.comparing;
019import static java.util.Optional.ofNullable;
020import static java.util.stream.Collectors.toList;
021
022import java.util.Arrays;
023import java.util.HashMap;
024import java.util.List;
025import java.util.Map;
026import java.util.ServiceLoader;
027import java.util.stream.StreamSupport;
028
029import org.talend.sdk.component.api.component.Metadatas;
030import org.talend.sdk.component.api.input.Emitter;
031import org.talend.sdk.component.api.input.PartitionMapper;
032import org.talend.sdk.component.api.meta.Documentation;
033import org.talend.sdk.component.spi.component.ComponentMetadataEnricher;
034
035import lombok.extern.slf4j.Slf4j;
036
037@Slf4j
038public class ComponentMetadataService {
039
040    private List<ComponentMetadataEnricher> enrichers;
041
042    private static final String DOCUMENTATION_KEY = "documentation::value";
043
044    public static final String MAPPER_INFINITE = "mapper::infinite";
045
046    public static final String MAPPER_OPTIONAL_ROW = "mapper::optionalRow";
047
048    public ComponentMetadataService() {
049        this.enrichers = StreamSupport
050                .stream(ServiceLoader.load(ComponentMetadataEnricher.class).spliterator(), false)
051                .collect(toList());
052    }
053
054    public Map<String, String> getMetadata(final Class<?> clazz) {
055        final Map<String, String> metas = new HashMap<>();
056        ofNullable(clazz.getAnnotation(Documentation.class)).ifPresent(d -> metas.put(DOCUMENTATION_KEY, d.value()));
057        ofNullable(clazz.getAnnotation(Metadatas.class))
058                .ifPresent(m -> Arrays.stream(m.value()).forEach(meta -> metas.put(meta.key(), meta.value())));
059        ofNullable(clazz.getAnnotation(PartitionMapper.class))
060                .ifPresent(pm -> {
061                    metas.put(MAPPER_INFINITE, Boolean.toString(pm.infinite()));
062                    metas.put(MAPPER_OPTIONAL_ROW, Boolean.toString(pm.optionalRow()));
063                });
064        ofNullable(clazz.getAnnotation(Emitter.class)).ifPresent(e -> {
065            metas.put(MAPPER_INFINITE, "false");
066            metas.put(MAPPER_OPTIONAL_ROW, Boolean.toString(e.optionalRow()));
067        });
068        // user defined spi
069        enrichers
070                .stream()
071                .sorted(comparing(ComponentMetadataEnricher::order))
072                .forEach(enricher -> enricher.onComponent(clazz, clazz.getAnnotations()).forEach((k, v) -> {
073                    if (metas.containsKey(k)) {
074                        log
075                                .warn("SPI {} (order: {}) overrides metadata {}.", enricher.getClass().getName(),
076                                        enricher.order(), k);
077                    }
078                    metas.put(k, v);
079                }));
080
081        return metas;
082    }
083
084}