001/**
002 * Copyright (C) 2006-2024 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}