001package com.streamconverter.controller; 002 003import com.streamconverter.command.CommandConfig; 004import com.streamconverter.command.impl.SampleStreamCommand; 005import com.streamconverter.command.impl.csv.CsvNavigateCommand; 006 007/** 008 * Controller for CSV data processing operations. 009 * 010 * <p>This controller demonstrates how to configure command pipelines for CSV processing. It 011 * provides several processing modes: 012 * 013 * <ul> 014 * <li>Column extraction - Extract specific columns by name or index 015 * <li>Row filtering - Filter rows based on criteria 016 * <li>Data transformation - Transform CSV data with additional processing 017 * <li>Validation - Validate CSV structure and content 018 * </ul> 019 * 020 * <p>Usage examples: 021 * 022 * <pre> 023 * // Extract specific column 024 * CsvProcessingController controller = CsvProcessingController.forColumnExtraction("name"); 025 * controller.process(inputStream, outputStream); 026 * 027 * // Complex processing pipeline 028 * CsvProcessingController controller = CsvProcessingController.forComplexProcessing("data", "processor-id"); 029 * controller.process(inputStream, outputStream); 030 * </pre> 031 * 032 * @author StreamConverter Team 033 * @version 1.0 034 * @since 1.0 035 */ 036public class CsvProcessingController extends AbstractStreamController { 037 038 /** Processing mode enumeration */ 039 public enum ProcessingMode { 040 /** Extract specific column data from CSV */ 041 COLUMN_EXTRACTION, 042 /** Perform complex multi-step processing */ 043 COMPLEX_PROCESSING, 044 /** Validate CSV format only */ 045 VALIDATION_ONLY, 046 /** Pass through CSV data unchanged */ 047 PASS_THROUGH 048 } 049 050 /** The processing mode for this controller */ 051 private final ProcessingMode mode; 052 053 /** Column name or index for extraction */ 054 private final String columnSelector; 055 056 /** Additional processor ID for complex processing */ 057 private final String processorId; 058 059 /** 060 * Creates a controller for column extraction. 061 * 062 * @param columnSelector the column name or index to extract 063 */ 064 private CsvProcessingController(String columnSelector) { 065 this.mode = ProcessingMode.COLUMN_EXTRACTION; 066 this.columnSelector = columnSelector; 067 this.processorId = null; 068 } 069 070 /** 071 * Creates a controller for complex processing. 072 * 073 * @param columnSelector the column name or index to extract 074 * @param processorId the processor ID for additional processing 075 */ 076 private CsvProcessingController(String columnSelector, String processorId) { 077 this.mode = ProcessingMode.COMPLEX_PROCESSING; 078 this.columnSelector = columnSelector; 079 this.processorId = processorId; 080 } 081 082 /** Creates a controller for pass-through processing. */ 083 private CsvProcessingController() { 084 this.mode = ProcessingMode.PASS_THROUGH; 085 this.columnSelector = null; 086 this.processorId = null; 087 } 088 089 /** 090 * Factory method for creating a column extraction controller. 091 * 092 * @param columnSelector column name or index to extract 093 * @return configured controller 094 */ 095 public static CsvProcessingController forColumnExtraction(String columnSelector) { 096 if (columnSelector == null || columnSelector.trim().isEmpty()) { 097 throw new IllegalArgumentException("Column selector cannot be null or empty"); 098 } 099 return new CsvProcessingController(columnSelector.trim()); 100 } 101 102 /** 103 * Factory method for creating a complex processing controller. 104 * 105 * @param columnSelector column name or index to extract 106 * @param processorId processor ID for additional processing 107 * @return configured controller 108 */ 109 public static CsvProcessingController forComplexProcessing( 110 String columnSelector, String processorId) { 111 if (columnSelector == null || columnSelector.trim().isEmpty()) { 112 throw new IllegalArgumentException("Column selector cannot be null or empty"); 113 } 114 if (processorId == null || processorId.trim().isEmpty()) { 115 throw new IllegalArgumentException("Processor ID cannot be null or empty"); 116 } 117 return new CsvProcessingController(columnSelector.trim(), processorId.trim()); 118 } 119 120 /** 121 * Factory method for creating a pass-through controller. 122 * 123 * @return configured controller that processes CSV without extraction 124 */ 125 public static CsvProcessingController forPassThrough() { 126 return new CsvProcessingController(); 127 } 128 129 /** 130 * Configures the command pipeline based on the processing mode. 131 * 132 * @return array of command configurations 133 */ 134 @Override 135 protected CommandConfig[] configureCommands() { 136 switch (mode) { 137 case COLUMN_EXTRACTION: 138 return new CommandConfig[] { 139 new CommandConfig( 140 CsvNavigateCommand.class, "Extract column: " + columnSelector, columnSelector) 141 }; 142 143 case COMPLEX_PROCESSING: 144 return new CommandConfig[] { 145 new CommandConfig( 146 CsvNavigateCommand.class, "Extract column: " + columnSelector, columnSelector), 147 new CommandConfig(SampleStreamCommand.class, "Process with: " + processorId, processorId) 148 }; 149 150 case VALIDATION_ONLY: 151 return new CommandConfig[] { 152 new CommandConfig(CsvNavigateCommand.class, "Validate CSV structure") 153 }; 154 155 case PASS_THROUGH: 156 return new CommandConfig[] { 157 new CommandConfig(CsvNavigateCommand.class, "Process entire CSV") 158 }; 159 160 default: 161 throw new IllegalStateException("Unknown processing mode: " + mode); 162 } 163 } 164 165 @Override 166 public String getInputDataType() { 167 return "CSV"; 168 } 169 170 @Override 171 public String getOutputDataType() { 172 switch (mode) { 173 case COLUMN_EXTRACTION: 174 return "CSV_COLUMN"; 175 case COMPLEX_PROCESSING: 176 return "PROCESSED_DATA"; 177 case VALIDATION_ONLY: 178 return "VALIDATION_RESULT"; 179 case PASS_THROUGH: 180 return "CSV"; 181 default: 182 return "UNKNOWN"; 183 } 184 } 185 186 /** 187 * Gets the processing mode of this controller. 188 * 189 * @return the processing mode 190 */ 191 public ProcessingMode getProcessingMode() { 192 return mode; 193 } 194 195 /** 196 * Gets the column selector if applicable. 197 * 198 * @return the column selector, or null if not applicable 199 */ 200 public String getColumnSelector() { 201 return columnSelector; 202 } 203 204 /** 205 * Gets the processor ID if applicable. 206 * 207 * @return the processor ID, or null if not applicable 208 */ 209 public String getProcessorId() { 210 return processorId; 211 } 212 213 @Override 214 public String getConfigurationDescription() { 215 StringBuilder desc = new StringBuilder(super.getConfigurationDescription()); 216 desc.append(" - Mode: ").append(mode); 217 218 if (columnSelector != null) { 219 desc.append(", Column: ").append(columnSelector); 220 } 221 222 if (processorId != null) { 223 desc.append(", Processor: ").append(processorId); 224 } 225 226 return desc.toString(); 227 } 228}