Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.jcustenborder.kafka.connect.xml.ConnectableHelper Maven / Gradle / Ivy
/**
* Copyright © 2017 Jeremy Custenborder ([email protected] )
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.jcustenborder.kafka.connect.xml;
import com.google.common.base.Preconditions;
import org.apache.kafka.connect.data.Schema;
import org.apache.kafka.connect.data.SchemaBuilder;
import org.apache.kafka.connect.data.Struct;
import org.apache.kafka.connect.errors.DataException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.function.Function;
public class ConnectableHelper {
public static final Schema QNAME_SCHEMA = qnameBuilder().build();
static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
private static final Logger log = LoggerFactory.getLogger(ConnectableHelper.class);
public static final SchemaBuilder qnameBuilder() {
return SchemaBuilder.struct()
.name(QName.class.getName())
.field("localPart", Schema.STRING_SCHEMA)
.field("prefix", Schema.OPTIONAL_STRING_SCHEMA)
.field("namespaceURI", Schema.OPTIONAL_STRING_SCHEMA);
}
public static void toInt64(Struct struct, String field, Number value) {
log.trace("toInt64() - field = '{}' value = '{}'", field, value);
Long result = null != value ? value.longValue() : null;
struct.put(field, result);
}
public static void toInt16(Struct struct, String field, Number value) {
log.trace("toInt16() - field = '{}' value = '{}'", field, value);
Short result = null != value ? value.shortValue() : null;
struct.put(field, result);
}
public static void toInt8(Struct struct, String field, Number value) {
log.trace("toInt8() - field = '{}' value = '{}'", field, value);
Byte result = null != value ? value.byteValue() : null;
struct.put(field, result);
}
public static void toFloat64(Struct struct, String field, Number value) {
log.trace("toFloat64() - field = '{}' value = '{}'", field, value);
Double result = null != value ? value.doubleValue() : null;
struct.put(field, result);
}
public static void toFloat32(Struct struct, String field, Number value) {
log.trace("addFloat32() - field = '{}' value = '{}'", field, value);
Float result = null != value ? value.floatValue() : null;
struct.put(field, result);
}
public static void toString(Struct struct, String field, String value) {
log.trace("toString() - field = '{}' value = '{}'", field, value);
struct.put(field, value);
}
public static void toDate(Struct struct, String field, XMLGregorianCalendar value) {
Date result;
if (null == value) {
result = null;
} else {
result = value.toGregorianCalendar().getTime();
}
struct.put(field, result);
}
public static String fromString(Struct struct, String field) {
log.trace("fromString() - field = '{}'", field);
return struct.getString(field);
}
public static Boolean fromBoolean(Struct struct, String field) {
log.trace("fromBoolean() - field = '{}'", field);
return struct.getBoolean(field);
}
public static void toBoolean(Struct struct, String field, Boolean value) {
log.trace("toBoolean() - field = '{}' value = '{}'", field, value);
struct.put(field, value);
}
public static Float fromFloat32(Struct struct, String field) {
log.trace("fromFloat32() - field = '{}'", field);
return struct.getFloat32(field);
}
public static XMLGregorianCalendar fromDate(Struct struct, String field) {
log.trace("fromDate() - field = '{}'", field);
return readXmlG(struct, field, Date.class, (xmlGregorianCalendar, connectValue) -> {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(connectValue);
xmlGregorianCalendar.setYear(calendar.get(Calendar.YEAR));
xmlGregorianCalendar.setMonth(calendar.get(Calendar.MONTH) + 1);
xmlGregorianCalendar.setDay(calendar.get(Calendar.DAY_OF_MONTH));
});
}
public static void toArray(Struct struct, String field, List> value) {
final List result;
if (null == value) {
result = null;
} else {
result = new ArrayList<>(value.size());
for (Object o : value) {
if (o instanceof Connectable) {
result.add(((Connectable)o).toStruct());
} else {
result.add(o);
}
}
}
struct.put(field, result);
}
public static List fromArray(Struct struct, String field, Class cls) {
List structs = struct.getArray(field);
List result;
if (null == structs) {
result = null;
} else {
result = new ArrayList<>(structs.size());
for (Object s : structs) {
if (s instanceof Struct && Connectable.class.isAssignableFrom(cls)) {
T o;
try {
o = cls.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
((Connectable)o).fromStruct((Struct)s);
result.add(o);
} else if (cls.isInstance(s)){
result.add(cls.cast(s));
} else {
throw new IllegalArgumentException("Element not castable to the target class");
}
}
}
return result;
}
public static Integer fromInt32(Struct struct, String field) {
log.trace("fromInt32() - field = '{}'", field);
return struct.getInt32(field);
}
public static Long fromInt64(Struct struct, String field) {
log.trace("fromInt64() - field = '{}'", field);
return struct.getInt64(field);
}
public static void toStruct(Struct struct, String field, Connectable value) {
log.trace("fromStruct() - field ='{}' value = '{}'", field, value);
Struct fieldStruct;
if (null == value) {
fieldStruct = null;
} else {
fieldStruct = value.toStruct();
}
struct.put(field, fieldStruct);
}
public static T fromStruct(Struct struct, String field, Class aClass) {
log.trace("fromStruct() - field ='{}' aClass = '{}'", field, aClass);
final T result;
Struct fieldStruct = struct.getStruct(field);
if (null == fieldStruct) {
result = null;
} else {
try {
result = aClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new DataException("Exception while creating instance of " + aClass.getName(), e);
}
result.fromStruct(fieldStruct);
}
return result;
}
public static void toBytes(Struct struct, String field, byte[] value) {
log.trace("toBytes() - field = '{}'", field);
struct.put(field, value);
}
public static void toDateTime(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toString() - field = '{}' value = '{}'", field, value);
Date result;
if (null == value) {
result = null;
} else {
result = value.toGregorianCalendar().getTime();
}
struct.put(field, result);
}
public static void toDecimal(Struct struct, String field, BigDecimal value) {
log.trace("toString() - field = '{}' value = '{}'", field, value);
struct.put(field, value);
}
public static void toXmlgDay(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toXmlgDay() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
return xmlGregorianCalendar.getDay();
}
});
}
public static void toXmlgMonth(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toXmlgMonth() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
return xmlGregorianCalendar.getMonth();
}
});
}
public static void toXmlgYear(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toXmlgYear() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
return xmlGregorianCalendar.getYear();
}
});
}
public static void toInt32(Struct struct, String field, Number value) {
log.trace("toInt32() - field = '{}' value = '{}'", field, value);
Integer result = null != value ? value.intValue() : null;
struct.put(field, result);
}
public static void toTime(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toTime() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
GregorianCalendar calendar = value.toGregorianCalendar(UTC_TIME_ZONE, null, null);
return calendar.getTime();
}
});
}
public static byte[] fromBytes(Struct struct, String field) {
log.trace("fromBytes() - field = '{}'", field);
return struct.getBytes(field);
}
public static Byte fromInt8(Struct struct, String field) {
log.trace("fromInt8() - field = '{}'", field);
return struct.getInt8(field);
}
public static XMLGregorianCalendar fromDateTime(Struct struct, String field) {
log.trace("fromDateTime() - field = '{}'", field);
XMLGregorianCalendar result;
Object value = struct.get(field);
if (null == value) {
result = null;
} else {
Preconditions.checkState(value instanceof Date, "%s(%s) should be a Date.", struct.schema().name(), field);
Date date = (Date) value;
GregorianCalendar c = new GregorianCalendar();
c.setTime(date);
try {
result = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
result.setTimezone(0);
} catch (DatatypeConfigurationException e) {
throw new DataException("Exception thrown", e);
}
}
return result;
}
public static BigDecimal fromDecimal(Struct struct, String field) {
log.trace("fromDecimal() - field = '{}'", field);
Object value = struct.get(field);
BigDecimal result = null == value ? null : (BigDecimal) value;
return result;
}
public static Double fromFloat64(Struct struct, String field) {
log.trace("fromFloat64() - field = '{}'", field);
return struct.getFloat64(field);
}
private static XMLGregorianCalendar createXMLGregorianCalendar() {
return createXMLGregorianCalendar(null);
}
private static XMLGregorianCalendar createXMLGregorianCalendar(GregorianCalendar calendar) {
XMLGregorianCalendar result;
try {
if (null == calendar) {
result = DatatypeFactory.newInstance().newXMLGregorianCalendar();
} else {
result = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
}
} catch (DatatypeConfigurationException e) {
throw new DataException("Exception while creating XMLGregorianCalendar", e);
}
return result;
}
public static XMLGregorianCalendar fromXmlgDay(Struct struct, String field) {
log.trace("fromXmlgDay() - field = '{}'", field);
return readXmlG(struct, field, Integer.class, new FromXmlG() {
@Override
public void apply(XMLGregorianCalendar xmlGregorianCalendar, Integer connectValue) {
xmlGregorianCalendar.setDay(connectValue);
}
});
}
public static BigInteger fromInt64BigInteger(Struct struct, String field) {
log.trace("fromInt64BigInteger() - field = '{}'", field);
Long value = struct.getInt64(field);
BigInteger result = null != value ? BigInteger.valueOf(value) : null;
return result;
}
public static Short fromInt16(Struct struct, String field) {
log.trace("fromInt16() - field = '{}'", field);
return struct.getInt16(field);
}
public static Struct fromQName(QName qName) {
Struct result = new Struct(QNAME_SCHEMA);
result.put("localPart", qName.getLocalPart());
result.put("prefix", qName.getPrefix());
result.put("namespaceURI", qName.getNamespaceURI());
return result;
}
public static QName toQName(Struct struct) {
final String localPart = struct.getString("localPart");
final String prefix = struct.getString("prefix");
final String namespaceURI = struct.getString("namespaceURI");
return new QName(namespaceURI, localPart, prefix);
}
public static void toQNameMap(Struct struct, String field, Map value) {
Map result;
if (null == value) {
result = null;
} else {
result = new LinkedHashMap<>(value.size());
for (Map.Entry e : value.entrySet()) {
Struct key = fromQName(e.getKey());
result.put(key, e.getValue());
}
}
struct.put(field, result);
}
public static Map fromQNameMap(Struct struct, String field) {
Map result;
Map structValue = struct.getMap(field);
if (null == structValue) {
result = null;
} else {
result = new LinkedHashMap<>();
for (Object k : structValue.keySet()) {
final Struct qNameStruct = (Struct) k;
final QName key = toQName(qNameStruct);
final String value = (String) structValue.get(k);
result.put(key, value);
}
}
return result;
}
public static XMLGregorianCalendar fromXmlgMonth(Struct struct, String field) {
log.trace("fromXmlgMonth() - field = '{}'", field);
return readXmlG(struct, field, Integer.class, new FromXmlG() {
@Override
public void apply(XMLGregorianCalendar xmlGregorianCalendar, Integer connectValue) {
xmlGregorianCalendar.setMonth(connectValue);
}
});
}
public static void toXmlgMonthDay(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toXmlgMonthDay() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
return xmlGregorianCalendar.toGregorianCalendar(UTC_TIME_ZONE, null, null).getTime();
}
});
}
public static void toXmlgYearMonth(Struct struct, String field, XMLGregorianCalendar value) {
log.trace("toXmlgYearMonth() - field = '{}' value = '{}'", field, value);
writeXmlG(struct, field, value, new Function() {
@Override
public Object apply(XMLGregorianCalendar xmlGregorianCalendar) {
return xmlGregorianCalendar.toGregorianCalendar(UTC_TIME_ZONE, null, null).getTime();
}
});
}
public static XMLGregorianCalendar fromXmlgMonthDay(Struct struct, String field) {
log.trace("fromXmlgMonthDay() - field = '{}'", field);
return readXmlG(struct, field, Date.class, new FromXmlG() {
@Override
public void apply(XMLGregorianCalendar xmlGregorianCalendar, Date connectValue) {
GregorianCalendar calendar = new GregorianCalendar(UTC_TIME_ZONE);
calendar.setTime(connectValue);
xmlGregorianCalendar.clear();
// XMLGregorianCalendar is 1 based for month - plain GregorianCalendar is 0 based.
xmlGregorianCalendar.setMonth(calendar.get(Calendar.MONTH) + 1);
xmlGregorianCalendar.setDay(calendar.get(Calendar.DAY_OF_MONTH));
}
});
}
public static XMLGregorianCalendar fromXmlgYearMonth(Struct struct, String field) {
log.trace("fromXmlgMonthDay() - field = '{}'", field);
return readXmlG(struct, field, Date.class, new FromXmlG() {
@Override
public void apply(XMLGregorianCalendar xmlGregorianCalendar, Date connectValue) {
GregorianCalendar calendar = new GregorianCalendar(UTC_TIME_ZONE);
calendar.setTime(connectValue);
xmlGregorianCalendar.clear();
// XMLGregorianCalendar is 1 based for month - plain GregorianCalendar is 0 based.
xmlGregorianCalendar.setMonth(calendar.get(Calendar.MONTH) + 1);
xmlGregorianCalendar.setYear(calendar.get(Calendar.YEAR));
}
});
}
public static XMLGregorianCalendar fromTime(Struct struct, String field) {
return readXmlG(struct, field, Date.class, (xmlGregorianCalendar, connectValue) -> {
GregorianCalendar calendar = new GregorianCalendar(UTC_TIME_ZONE);
calendar.setTime(connectValue);
xmlGregorianCalendar.setTime(
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND)
);
xmlGregorianCalendar.setTimezone(0);
});
}
public static void toQname(Struct struct, String field, QName value) {
log.trace("toQname() - field = '{}' value ='{}'", field, value);
Struct fieldStruct;
if (null == value) {
fieldStruct = null;
} else {
fieldStruct = fromQName(value);
}
struct.put(field, fieldStruct);
}
public static QName fromQname(Struct struct, String field) {
QName result;
Struct fieldStruct = struct.getStruct(field);
if (null == fieldStruct) {
result = null;
} else {
result = toQName(struct);
}
return result;
}
public static void toDuration(Struct struct, String field, Duration value) {
log.trace("toDuration() - field = '{}' value ='{}'", field, value);
Long connectValue;
if (value == null) {
connectValue = null;
} else {
connectValue = value.getTimeInMillis(new Date(0));
}
log.trace(
"toDuration() - field = '{}' connectValue = '{}' result = '{}'",
field,
value,
connectValue
);
struct.put(field, connectValue);
}
public static Duration fromDuration(Struct struct, String field) {
log.trace("toDuration() - field = '{}'", field);
Duration result;
Long connectValue = struct.getInt64(field);
if (null == connectValue) {
result = null;
} else {
try {
result = DatatypeFactory.newInstance().newDuration(connectValue);
} catch (DatatypeConfigurationException e) {
throw new DataException("Exception while creating Duration", e);
}
}
log.trace(
"fromDuration() - field = '{}' connectValue = '{}' result = '{}'",
field,
result,
connectValue
);
return result;
}
static void writeXmlG(Struct struct, String field, XMLGregorianCalendar value, Function function) {
log.trace("writeXmlG() - field = '{}' value = '{}'", field, value);
Object result;
if (null == value) {
result = null;
} else {
result = function.apply(value);
}
log.trace(
"writeXmlG() - field = '{}' connectValue = '{}' result = '{}'",
field,
value,
result
);
struct.put(field, result);
}
static XMLGregorianCalendar readXmlG(Struct struct, String field, Class storageClass, FromXmlG transform) {
log.trace("readXmlG() - field = '{}'", field);
final XMLGregorianCalendar result;
Object v = struct.get(field);
if (null == v) {
result = null;
} else {
if (!storageClass.isInstance(v)) {
throw new DataException(
String.format(
"Field %s(%s) was expected to be a %s but was %s.",
struct.schema().name(),
field,
storageClass.getName(),
v.getClass().getName()
)
);
}
T connectValue = storageClass.cast(v);
XMLGregorianCalendar calendar = createXMLGregorianCalendar();
transform.apply(calendar, connectValue);
result = calendar;
}
log.trace(
"readXmlG() - field = '{}' connectValue = '{}' result = '{}'",
field,
v,
result
);
return result;
}
public static XMLGregorianCalendar fromXmlgYear(Struct struct, String field) {
log.trace("fromXmlgYear() - field = '{}'", field);
return readXmlG(struct, field, Integer.class, (xmlGregorianCalendar, connectValue) -> {
xmlGregorianCalendar.setYear(connectValue);
});
}
public static void fromEnum(final Struct struct, final String field, final Enum enumClass) {
struct.put(field, enumClass.name());
}
public static T toEnum(final Struct struct, final String field, final Class enumType) {
return (T) Enum.valueOf(enumType, struct.getString(field));
}
interface FromXmlG {
void apply(XMLGregorianCalendar xmlGregorianCalendar, T connectValue);
}
}