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.service.api; 017 018import java.util.Map; 019import java.util.Objects; 020import java.util.Optional; 021import java.util.function.Supplier; 022import java.util.stream.Stream; 023 024import org.talend.sdk.component.runtime.base.Lifecycle; 025import org.talend.sdk.component.runtime.manager.ComponentFamilyMeta; 026import org.talend.sdk.component.runtime.manager.ComponentManager.ComponentType; 027import org.talend.sdk.component.runtime.manager.ContainerComponentRegistry; 028 029import lombok.RequiredArgsConstructor; 030import lombok.extern.slf4j.Slf4j; 031 032@FunctionalInterface 033public interface ComponentInstantiator { 034 035 Lifecycle instantiate(final Map<String, String> configuration, final int configVersion); 036 037 interface MetaFinder { 038 039 Optional<? extends ComponentFamilyMeta.BaseMeta> 040 filter(final Map<String, ? extends ComponentFamilyMeta.BaseMeta> source); 041 042 static MetaFinder ofComponent(final String name) { 043 return new ComponentNameFinder(name); 044 } 045 } 046 047 @FunctionalInterface 048 interface Builder { 049 050 ComponentInstantiator build(final String familyName, final MetaFinder finder, 051 final ComponentType componentType); 052 } 053 054 @Slf4j 055 @RequiredArgsConstructor 056 class BuilderDefault implements Builder { 057 058 private final Supplier<Stream<ContainerComponentRegistry>> registrySupplier; 059 060 @Override 061 public ComponentInstantiator build(final String familyName, final MetaFinder finder, 062 final ComponentType componentType) { 063 final Stream<ContainerComponentRegistry> registries = this.registrySupplier.get(); 064 if (registries == null) { 065 return null; 066 } 067 final String sanitizedFamilyName = Optional.ofNullable(familyName).map(String::trim).orElse(""); 068 return registries 069 .map((ContainerComponentRegistry registry) -> registry.findComponentFamily(sanitizedFamilyName)) 070 .filter(Objects::nonNull) 071 .peek((ComponentFamilyMeta cm) -> log.debug("Family found {} plugin {}", sanitizedFamilyName, 072 cm.getPlugin())) 073 .map(componentType::findMeta) 074 .map((Map<String, ? extends ComponentFamilyMeta.BaseMeta> map) -> finder.filter(map)) 075 .filter(Optional::isPresent) 076 .map(Optional::get) 077 .findFirst() 078 .map((ComponentFamilyMeta.BaseMeta c) -> (ComponentInstantiator) c::instantiate) 079 .orElse(null); 080 } 081 } 082 083 @Slf4j 084 class ComponentNameFinder implements MetaFinder { 085 086 private final String componentName; 087 088 public ComponentNameFinder(final String componentName) { 089 this.componentName = Optional.ofNullable(componentName).map(String::trim).orElse(""); 090 } 091 092 @Override 093 public Optional<? extends ComponentFamilyMeta.BaseMeta> 094 filter(final Map<String, ? extends ComponentFamilyMeta.BaseMeta> source) { 095 if (!source.containsKey(this.componentName)) { 096 log.debug("Can't find component name {}", this.componentName); 097 } 098 return Optional.ofNullable(source.get(this.componentName)); 099 } 100 } 101}