View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.data.pipeline.cdc.util;
19  
20  import com.google.protobuf.BoolValue;
21  import com.google.protobuf.ByteString;
22  import com.google.protobuf.BytesValue;
23  import com.google.protobuf.DoubleValue;
24  import com.google.protobuf.Empty;
25  import com.google.protobuf.FloatValue;
26  import com.google.protobuf.Int32Value;
27  import com.google.protobuf.Int64Value;
28  import com.google.protobuf.Message;
29  import com.google.protobuf.StringValue;
30  import lombok.AccessLevel;
31  import lombok.NoArgsConstructor;
32  import lombok.SneakyThrows;
33  
34  import java.math.BigDecimal;
35  import java.math.BigInteger;
36  import java.sql.Blob;
37  import java.sql.Clob;
38  import java.sql.SQLException;
39  import java.sql.Time;
40  import java.sql.Timestamp;
41  import java.time.Instant;
42  import java.time.LocalDate;
43  import java.time.LocalDateTime;
44  import java.time.LocalTime;
45  import java.time.OffsetDateTime;
46  import java.time.OffsetTime;
47  import java.time.ZonedDateTime;
48  import java.util.Date;
49  
50  /**
51   * Column value convert utility class.
52   */
53  @NoArgsConstructor(access = AccessLevel.PRIVATE)
54  public final class ColumnValueConvertUtils {
55      
56      /**
57       * Convert java object to protobuf message.
58       *
59       * @param object object
60       * @return protobuf message
61       * @throws RuntimeException runtime exception
62       */
63      @SuppressWarnings("deprecation")
64      @SneakyThrows(SQLException.class)
65      public static Message convertToProtobufMessage(final Object object) {
66          if (null == object) {
67              return Empty.getDefaultInstance();
68          }
69          if (object instanceof Integer) {
70              return Int32Value.of((int) object);
71          }
72          if (object instanceof Short) {
73              return Int32Value.of(((Short) object).intValue());
74          }
75          if (object instanceof Byte) {
76              return Int32Value.of(((Byte) object).intValue());
77          }
78          if (object instanceof Long) {
79              return Int64Value.of((long) object);
80          }
81          if (object instanceof BigInteger) {
82              return StringValue.of(object.toString());
83          }
84          if (object instanceof Float) {
85              return FloatValue.of((float) object);
86          }
87          if (object instanceof Double) {
88              return DoubleValue.of((double) object);
89          }
90          if (object instanceof BigDecimal) {
91              return StringValue.of(object.toString());
92          }
93          if (object instanceof String) {
94              return StringValue.of(object.toString());
95          }
96          if (object instanceof Boolean) {
97              return BoolValue.of((boolean) object);
98          }
99          if (object instanceof byte[]) {
100             return BytesValue.of(ByteString.copyFrom((byte[]) object));
101         }
102         if (object instanceof Time) {
103             Time time = (Time) object;
104             LocalTime localTime = LocalTime.of(time.getHours(), time.getMinutes(), time.getSeconds(), new Timestamp(time.getTime()).getNanos());
105             return Int64Value.of(localTime.toNanoOfDay());
106         }
107         if (object instanceof java.sql.Date) {
108             return Int64Value.of(((java.sql.Date) object).toLocalDate().toEpochDay());
109         }
110         if (object instanceof Date) {
111             return converToProtobufTimestamp((Date) object);
112         }
113         if (object instanceof LocalDateTime) {
114             return converToProtobufTimestamp(Timestamp.valueOf((LocalDateTime) object));
115         }
116         if (object instanceof LocalDate) {
117             return Int64Value.of(((LocalDate) object).toEpochDay());
118         }
119         if (object instanceof LocalTime) {
120             return Int64Value.of(((LocalTime) object).toNanoOfDay());
121         }
122         if (object instanceof OffsetDateTime) {
123             LocalDateTime localDateTime = ((OffsetDateTime) object).toLocalDateTime();
124             return converToProtobufTimestamp(Timestamp.valueOf(localDateTime));
125         }
126         if (object instanceof OffsetTime) {
127             return Int64Value.of(((OffsetTime) object).toLocalTime().toNanoOfDay());
128         }
129         if (object instanceof ZonedDateTime) {
130             return converToProtobufTimestamp(Timestamp.valueOf(((ZonedDateTime) object).toLocalDateTime()));
131         }
132         if (object instanceof Instant) {
133             Instant instant = (Instant) object;
134             return com.google.protobuf.Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build();
135         }
136         if (object instanceof Clob) {
137             Clob clob = (Clob) object;
138             return StringValue.of(clob.getSubString(1, (int) clob.length()));
139         }
140         if (object instanceof Blob) {
141             Blob blob = (Blob) object;
142             return BytesValue.of(ByteString.copyFrom(blob.getBytes(1, (int) blob.length())));
143         }
144         return StringValue.newBuilder().setValue(object.toString()).build();
145     }
146     
147     private static com.google.protobuf.Timestamp converToProtobufTimestamp(final Date timestamp) {
148         if (timestamp instanceof Timestamp) {
149             Timestamp value = (Timestamp) timestamp;
150             return com.google.protobuf.Timestamp.newBuilder().setSeconds(value.getTime() / 1000).setNanos(value.getNanos()).build();
151         }
152         long millis = timestamp.getTime();
153         return com.google.protobuf.Timestamp.newBuilder().setSeconds(millis / 1000).setNanos((int) ((millis % 1000) * 1000000)).build();
154     }
155 }