001/** 002 * Copyright (C) 2006-2026 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.api.processor; 017 018import java.util.Iterator; 019 020/** 021 * Allows a processor to stream records lazily to multiple output connections 022 * without buffering, supporting two mutually exclusive modes per invocation: 023 * 024 * <ul> 025 * <li><b>Split mode</b> ({@link #setIterator(Iterator)}): a single tagged iterator 026 * routes each record to a specific output connection via {@link TaggedOutput}. 027 * Use when records come from one shared source and must be split between outputs.</li> 028 * <li><b>Independent mode</b> ({@link #setIterator(String, Iterator)}): each output 029 * connection gets its own independent lazy iterator, consumed in parallel by the drain 030 * loop. Use when each output has its own self-contained lazy source.</li> 031 * </ul> 032 * 033 * <p> 034 * Both modes can be selected at runtime from the same fixed method parameter, 035 * so the component does not need separate parameters per output. 036 * 037 * <p> 038 * It is equally valid to use it with a <b>single</b> output: the point is then to stream records lazily 039 * instead of pushing them through an {@link OutputEmitter}, which avoids buffering. In that case the 040 * branch is named as usual with {@code @Output("FLOW")}; {@code @Output(branches = ...)} is only needed 041 * when the parameter feeds several branches, to declare them to the design layer. 042 * 043 * <p> 044 * <b>Important:</b> This interface is supported only in the Studio DI runtime. 045 * 046 * <p> 047 * <b>Split mode example</b> (one source, per-record routing): 048 * 049 * <pre> 050 * {@code 051 * 052 * @ElementListener 053 * public void process(@Input Record input, 054 * @Output(branches = { "MAIN", "REJECT" }) MultiOutputIterator<Record> out) { 055 * out.setIterator( 056 * mySource.stream() 057 * .map(r -> isValid(r) 058 * ? TaggedOutput.of("MAIN", transform(r)) 059 * : TaggedOutput.of("REJECT", r)) 060 * .iterator()); 061 * } 062 * } 063 * </pre> 064 * 065 * <p> 066 * <b>Independent mode example</b> (each output has its own lazy source): 067 * 068 * <pre> 069 * {@code 070 * 071 * @AfterGroup 072 * public void afterGroup(@Output(branches = { "MAIN", "REJECT" }) MultiOutputIterator<Record> out) { 073 * out.setIterator("MAIN", mainDatabase.lazyQuery()); 074 * out.setIterator("REJECT", errorLog.lazyRead()); 075 * } 076 * } 077 * </pre> 078 * 079 * @param <T> the record type 080 * @see TaggedOutput 081 */ 082public interface MultiOutputIterator<T> { 083 084 /** 085 * <b>Split mode</b>: sets a single lazy iterator whose elements are tagged with 086 * the target output connection name via {@link TaggedOutput}. 087 * The runtime reads one record at a time and routes it to the matching connection. 088 * 089 * <p> 090 * Mutually exclusive with {@link #setIterator(String, Iterator)} within one invocation. 091 * 092 * @param iterator the tagged iterator routing records to their named outputs 093 */ 094 void setIterator(Iterator<TaggedOutput<T>> iterator); 095 096 /** 097 * <b>Independent mode</b>: assigns a lazy iterator to a specific named output connection. 098 * Call once per output that needs a dedicated lazy source; connections without an 099 * assigned iterator fall back to the push-mode queue as usual. 100 * 101 * <p> 102 * Mutually exclusive with {@link #setIterator(Iterator)} within one invocation. 103 * 104 * @param outputName the output connection name (e.g. {@code "MAIN"}, {@code "REJECT"}) 105 * @param iterator the lazy iterator producing records for that connection 106 */ 107 void setIterator(String outputName, Iterator<T> iterator); 108}