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.record; 017 018import static java.util.function.Function.identity; 019import static java.util.stream.Collectors.toMap; 020 021import java.io.ObjectStreamException; 022import java.io.Serializable; 023import java.util.Map; 024 025import org.talend.sdk.component.api.record.Record; 026import org.talend.sdk.component.api.record.Schema; 027import org.talend.sdk.component.api.service.record.RecordBuilderFactory; 028import org.talend.sdk.component.runtime.serialization.SerializableService; 029 030import lombok.Data; 031 032@Data 033public class RecordBuilderFactoryImpl implements RecordBuilderFactory, Serializable { 034 035 protected final String plugin; 036 037 @Override 038 public Schema.Builder newSchemaBuilder(final Schema.Type type) { 039 switch (type) { 040 case RECORD: 041 case ARRAY: 042 return new SchemaImpl.BuilderImpl().withType(type); 043 default: 044 return Schemas.valueOf(type.name()); 045 } 046 } 047 048 @Override 049 public Schema.Builder newSchemaBuilder(final Schema schema) { 050 final Schema.Builder builder = newSchemaBuilder(schema.getType()); 051 switch (schema.getType()) { 052 case RECORD: 053 schema.getAllEntries().forEach(builder::withEntry); 054 break; 055 case ARRAY: 056 builder.withElementSchema(schema.getElementSchema()); 057 break; 058 default: 059 } 060 return builder; 061 } 062 063 @Override 064 public Record.Builder newRecordBuilder(final Schema schema, final Record record) { 065 final Record.Builder builder = newRecordBuilder(schema); 066 final Map<String, Schema.Entry> entriesIndex = 067 schema.getAllEntries().collect(toMap(Schema.Entry::getName, identity())); 068 record.getSchema().getAllEntries().filter(e -> entriesIndex.containsKey(e.getName())).forEach(entry -> { 069 switch (entry.getType()) { 070 case STRING: 071 record 072 .getOptionalString(entry.getName()) 073 .ifPresent(v -> builder.withString(entriesIndex.get(entry.getName()), v)); 074 break; 075 case LONG: 076 record 077 .getOptionalLong(entry.getName()) 078 .ifPresent(v -> builder.withLong(entriesIndex.get(entry.getName()), v)); 079 break; 080 case INT: 081 record 082 .getOptionalInt(entry.getName()) 083 .ifPresent(v -> builder.withInt(entriesIndex.get(entry.getName()), v)); 084 break; 085 case DOUBLE: 086 record 087 .getOptionalDouble(entry.getName()) 088 .ifPresent(v -> builder.withDouble(entriesIndex.get(entry.getName()), v)); 089 break; 090 case FLOAT: 091 record 092 .getOptionalFloat(entry.getName()) 093 .ifPresent(v -> builder.withFloat(entriesIndex.get(entry.getName()), (float) v)); 094 break; 095 case BOOLEAN: 096 record 097 .getOptionalBoolean(entry.getName()) 098 .ifPresent(v -> builder.withBoolean(entriesIndex.get(entry.getName()), v)); 099 break; 100 case BYTES: 101 record 102 .getOptionalBytes(entry.getName()) 103 .ifPresent(v -> builder.withBytes(entriesIndex.get(entry.getName()), v)); 104 break; 105 case DATETIME: 106 record 107 .getOptionalDateTime(entry.getName()) 108 .ifPresent(v -> builder.withDateTime(entriesIndex.get(entry.getName()), v)); 109 break; 110 case DECIMAL: 111 record 112 .getOptionalDecimal(entry.getName()) 113 .ifPresent(v -> builder.withDecimal(entriesIndex.get(entry.getName()), v)); 114 break; 115 case RECORD: 116 record 117 .getOptionalRecord(entry.getName()) 118 .ifPresent(v -> builder.withRecord(entriesIndex.get(entry.getName()), v)); 119 break; 120 case ARRAY: 121 record 122 .getOptionalArray(Object.class, entry.getName()) 123 .ifPresent(v -> builder.withArray(entriesIndex.get(entry.getName()), v)); 124 break; 125 default: 126 throw new IllegalArgumentException("Unsupported entry type: " + entry); 127 } 128 }); 129 return builder; 130 } 131 132 @Override 133 public Record.Builder newRecordBuilder(final Schema schema) { 134 return new RecordImpl.BuilderImpl(schema); 135 } 136 137 @Override 138 public Record.Builder newRecordBuilder() { 139 return new RecordImpl.BuilderImpl(); 140 } 141 142 @Override 143 public Schema.Entry.Builder newEntryBuilder() { 144 return new SchemaImpl.EntryImpl.BuilderImpl(); 145 } 146 147 Object writeReplace() throws ObjectStreamException { 148 return new SerializableService(plugin, RecordBuilderFactory.class.getName()); 149 } 150}