001/**
002 * Copyright (C) 2006-2018 Talend Inc. - www.talend.com
003 * <p>
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 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
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.record;
017
018import static java.util.Optional.ofNullable;
019
020import java.time.ZonedDateTime;
021import java.util.Collection;
022import java.util.Date;
023import java.util.Optional;
024import java.util.OptionalDouble;
025import java.util.OptionalInt;
026import java.util.OptionalLong;
027
028public interface Record {
029
030    /**
031     * @return the schema of this record.
032     */
033    Schema getSchema();
034
035    /**
036     * Access a record field value.
037     *
038     * IMPORTANT: it is always better to use the typed accessors and the optional flavor when the entry is nullable.
039     *
040     * @param expectedType the expected type for the column.
041     * @param name the name of the column.
042     * @param <T> the type of expectedType.
043     * @return the column value.
044     */
045    <T> T get(Class<T> expectedType, String name);
046
047    /**
048     * See {@link Record#get(Class, String)}.
049     * 
050     * @param name entry name.
051     * @return the value of the entry in this record.
052     */
053    default String getString(final String name) {
054        return get(String.class, name);
055    }
056
057    /**
058     * See {@link Record#get(Class, String)}.
059     * 
060     * @param name entry name.
061     * @return the value of the entry in this record.
062     */
063    default int getInt(final String name) {
064        return get(Integer.class, name);
065    }
066
067    /**
068     * See {@link Record#get(Class, String)}.
069     * 
070     * @param name entry name.
071     * @return the value of the entry in this record.
072     */
073    default long getLong(final String name) {
074        return get(Long.class, name);
075    }
076
077    /**
078     * See {@link Record#get(Class, String)}.
079     * 
080     * @param name entry name.
081     * @return the value of the entry in this record.
082     */
083    default double getDouble(final String name) {
084        return get(Double.class, name);
085    }
086
087    /**
088     * See {@link Record#get(Class, String)}.
089     * 
090     * @param name entry name.
091     * @return the value of the entry in this record.
092     */
093    default float getFloat(final String name) {
094        return get(Float.class, name);
095    }
096
097    /**
098     * See {@link Record#get(Class, String)}.
099     * 
100     * @param name entry name.
101     * @return the value of the entry in this record.
102     */
103    default boolean getBoolean(final String name) {
104        return get(Boolean.class, name);
105    }
106
107    /**
108     * See {@link Record#get(Class, String)}.
109     * 
110     * @param name entry name.
111     * @return the value of the entry in this record.
112     */
113    default byte[] getBytes(final String name) {
114        return get(byte[].class, name);
115    }
116
117    /**
118     * See {@link Record#get(Class, String)}.
119     * 
120     * @param name entry name.
121     * @return the value of the entry in this record.
122     */
123    default Record getRecord(final String name) {
124        return get(Record.class, name);
125    }
126
127    /**
128     * See {@link Record#get(Class, String)}.
129     * 
130     * @param type type of the elements of the collection.
131     * @param name entry name.
132     * @return the value of the entry in this record.
133     */
134    default <T> Collection<T> getArray(final Class<T> type, final String name) {
135        return get(Collection.class, name);
136    }
137
138    /**
139     * See {@link Record#get(Class, String)}.
140     * 
141     * @param name entry name.
142     * @return the value of the entry in this record.
143     */
144    default ZonedDateTime getDateTime(final String name) {
145        return get(ZonedDateTime.class, name);
146    }
147
148    /**
149     * See {@link Record#get(Class, String)}.
150     * 
151     * @param type type of the elements of the collection.
152     * @param name entry name.
153     * @return the value of the entry in this record.
154     */
155    default <T> Optional<Collection<T>> getOptionalArray(final Class<T> type, final String name) {
156        final Collection<T> value = get(Collection.class, name);
157        return ofNullable(value);
158    }
159
160    /**
161     * See {@link Record#get(Class, String)}.
162     * 
163     * @param name entry name.
164     * @return the value of the entry in this record.
165     */
166    default Optional<ZonedDateTime> getOptionalDateTime(final String name) {
167        return ofNullable(get(ZonedDateTime.class, name));
168    }
169
170    /**
171     * See {@link Record#get(Class, String)}.
172     * 
173     * @param name entry name.
174     * @return the value of the entry in this record.
175     */
176    default Optional<String> getOptionalString(final String name) {
177        return ofNullable(get(String.class, name));
178    }
179
180    /**
181     * See {@link Record#get(Class, String)}.
182     * 
183     * @param name entry name.
184     * @return the value of the entry in this record.
185     */
186    default OptionalInt getOptionalInt(final String name) {
187        final Integer value = get(Integer.class, name);
188        return value == null ? OptionalInt.empty() : OptionalInt.of(value);
189    }
190
191    /**
192     * See {@link Record#get(Class, String)}.
193     * 
194     * @param name entry name.
195     * @return the value of the entry in this record.
196     */
197    default OptionalLong getOptionalLong(final String name) {
198        final Long value = get(Long.class, name);
199        return value == null ? OptionalLong.empty() : OptionalLong.of(value);
200    }
201
202    /**
203     * See {@link Record#get(Class, String)}.
204     * 
205     * @param name entry name.
206     * @return the value of the entry in this record.
207     */
208    default OptionalDouble getOptionalDouble(final String name) {
209        final Double value = get(Double.class, name);
210        return value == null ? OptionalDouble.empty() : OptionalDouble.of(value);
211    }
212
213    /**
214     * See {@link Record#get(Class, String)}.
215     * 
216     * @param name entry name.
217     * @return the value of the entry in this record.
218     */
219    default OptionalDouble getOptionalFloat(final String name) {
220        final Float value = get(Float.class, name);
221        return value == null ? OptionalDouble.empty() : OptionalDouble.of(value);
222    }
223
224    /**
225     * See {@link Record#get(Class, String)}.
226     * 
227     * @param name entry name.
228     * @return the value of the entry in this record.
229     */
230    default Optional<Boolean> getOptionalBoolean(final String name) {
231        return ofNullable(get(Boolean.class, name));
232    }
233
234    /**
235     * See {@link Record#get(Class, String)}.
236     * 
237     * @param name entry name.
238     * @return the value of the entry in this record.
239     */
240    default Optional<byte[]> getOptionalBytes(final String name) {
241        return ofNullable(get(byte[].class, name));
242    }
243
244    /**
245     * See {@link Record#get(Class, String)}.
246     * 
247     * @param name entry name.
248     * @return the value of the entry in this record.
249     */
250    default Optional<Record> getOptionalRecord(final String name) {
251        return ofNullable(get(Record.class, name));
252    }
253
254    /**
255     * Allows to create a record with a fluent API. This is the unique recommended way to create a record.
256     */
257    interface Builder {
258
259        Record build();
260
261        Builder withString(String name, String value);
262
263        Builder withString(Schema.Entry entry, String value);
264
265        Builder withBytes(String name, byte[] value);
266
267        Builder withBytes(Schema.Entry entry, byte[] value);
268
269        Builder withDateTime(String name, Date value);
270
271        Builder withDateTime(Schema.Entry entry, Date value);
272
273        Builder withDateTime(String name, ZonedDateTime value);
274
275        Builder withDateTime(Schema.Entry entry, ZonedDateTime value);
276
277        Builder withTimestamp(String name, long value);
278
279        Builder withTimestamp(Schema.Entry entry, long value);
280
281        Builder withInt(String name, int value);
282
283        Builder withInt(Schema.Entry entry, int value);
284
285        Builder withLong(String name, long value);
286
287        Builder withLong(Schema.Entry entry, long value);
288
289        Builder withFloat(String name, float value);
290
291        Builder withFloat(Schema.Entry entry, float value);
292
293        Builder withDouble(String name, double value);
294
295        Builder withDouble(Schema.Entry entry, double value);
296
297        Builder withBoolean(String name, boolean value);
298
299        Builder withBoolean(Schema.Entry entry, boolean value);
300
301        Builder withRecord(Schema.Entry entry, Record value);
302
303        <T> Builder withArray(Schema.Entry entry, Collection<T> values);
304    }
305}