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.design.extension; 017 018import static java.util.Optional.ofNullable; 019 020import java.util.Collection; 021import java.util.stream.Stream; 022 023import org.talend.sdk.component.container.Container; 024import org.talend.sdk.component.design.extension.flows.FlowsFactory; 025import org.talend.sdk.component.design.extension.repository.RepositoryModelBuilder; 026import org.talend.sdk.component.runtime.manager.ComponentFamilyMeta; 027import org.talend.sdk.component.runtime.manager.ComponentManager; 028import org.talend.sdk.component.runtime.manager.ContainerComponentRegistry; 029import org.talend.sdk.component.runtime.manager.extension.ComponentContexts; 030import org.talend.sdk.component.runtime.manager.reflect.MigrationHandlerFactory; 031import org.talend.sdk.component.runtime.manager.spi.ContainerListenerExtension; 032import org.talend.sdk.component.spi.component.ComponentExtension; 033 034/** 035 * Service provider for {@link ContainerListenerExtension} service 036 */ 037public class DesignContainerListener implements ContainerListenerExtension { 038 039 private final RepositoryModelBuilder repositoryModelBuilder = new RepositoryModelBuilder(); 040 041 private MigrationHandlerFactory migrationHandlerFactory; 042 043 @Override 044 public void setComponentManager(final ComponentManager manager) { 045 migrationHandlerFactory = manager.getMigrationHandlerFactory(); 046 } 047 048 /** 049 * Enriches {@link Container} with {@link DesignModel} and 050 * {@link RepositoryModel} It depends on Updater listener which adds 051 * {@link ContainerComponentRegistry} class to {@link Container} 052 */ 053 @Override 054 public void onCreate(final Container container) { 055 final ContainerComponentRegistry componentRegistry = container.get(ContainerComponentRegistry.class); 056 057 if (componentRegistry == null) { 058 throw new IllegalArgumentException("container doesn't contain ContainerComponentRegistry"); 059 } 060 061 final Collection<ComponentFamilyMeta> componentFamilyMetas = componentRegistry.getComponents().values(); 062 063 // Create Design Model 064 componentFamilyMetas 065 .stream() 066 .flatMap(family -> Stream 067 .of(family.getPartitionMappers().values().stream(), family.getProcessors().values().stream(), 068 family.getDriverRunners().values().stream()) 069 .flatMap(t -> t)) 070 .forEach(meta -> { 071 final ComponentExtension.ComponentContext context = 072 container.get(ComponentContexts.class).getContexts().get(meta.getType()); 073 final ComponentExtension owningExtension = context.owningExtension(); 074 meta 075 .set(DesignModel.class, ofNullable(owningExtension) 076 .map(e -> e.unwrap(FlowsFactory.class, meta)) 077 .map(e -> new DesignModel(meta.getId(), e.getInputFlows(), e.getOutputFlows())) 078 .orElseGet(() -> { 079 final FlowsFactory factory = FlowsFactory.get(meta); 080 return new DesignModel(meta.getId(), factory.getInputFlows(), 081 factory.getOutputFlows()); 082 })); 083 }); 084 085 // Create Repository Model 086 container 087 .set(RepositoryModel.class, 088 repositoryModelBuilder 089 .create(container.get(ComponentManager.AllServices.class), componentFamilyMetas, 090 migrationHandlerFactory)); 091 } 092 093 /** 094 * It relies on Updater listener onClose() method which removes all 095 * ComponentFamilyMeta from Container Thus, this listener has nothing to do on 096 * close 097 */ 098 @Override 099 public void onClose(final Container container) { 100 // no-op 101 } 102 103}