[jOOQ/jOOQ#10532] Add new <lambdaConverter/> configuration in <forcedType/> to further simplify programmatic converters
This commit is contained in:
parent
192be43181
commit
dc1f3dc6ae
@ -1310,8 +1310,9 @@ public abstract class AbstractDatabase implements Database {
|
||||
|
||||
if (StringUtils.isBlank(type.getBinding()) &&
|
||||
StringUtils.isBlank(type.getConverter()) &&
|
||||
!Boolean.TRUE.equals(type.isEnumConverter())) {
|
||||
log.warn("Bad configuration for <forcedType/>. Either <binding/> or <converter/> or <enumConverter/> is required: " + type);
|
||||
!Boolean.TRUE.equals(type.isEnumConverter()) &&
|
||||
type.getLambdaConverter() == null) {
|
||||
log.warn("Bad configuration for <forcedType/>. Either <binding/> or <converter/> or <enumConverter/> or <lambdaConverter/> is required: " + type);
|
||||
|
||||
it2.remove();
|
||||
continue;
|
||||
@ -1334,6 +1335,10 @@ public abstract class AbstractDatabase implements Database {
|
||||
log.warn("Bad configuration for <forcedType/>. <enumConverter/> is not allowed when <name/> is provided: " + type);
|
||||
type.setEnumConverter(null);
|
||||
}
|
||||
if (type.getLambdaConverter() != null) {
|
||||
log.warn("Bad configuration for <forcedType/>. <lambdaConverter/> is not allowed when <name/> is provided: " + type);
|
||||
type.setLambdaConverter(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.getUserType() != null && StringUtils.equals(type.getUserType(), typeName)) {
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
package org.jooq.meta;
|
||||
|
||||
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static org.jooq.tools.Convert.convert;
|
||||
import static org.jooq.tools.StringUtils.isEmpty;
|
||||
|
||||
@ -57,6 +58,7 @@ import org.jooq.impl.EnumConverter;
|
||||
import org.jooq.impl.SQLDataType;
|
||||
import org.jooq.meta.jaxb.CustomType;
|
||||
import org.jooq.meta.jaxb.ForcedType;
|
||||
import org.jooq.meta.jaxb.LambdaConverter;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
@ -225,21 +227,14 @@ public abstract class AbstractTypedElementDefinition<T extends Definition>
|
||||
// [#5877] [#6567] EnumConverters profit from simplified configuration
|
||||
if (Boolean.TRUE.equals(customType.isEnumConverter()) ||
|
||||
EnumConverter.class.getName().equals(customType.getConverter())) {
|
||||
|
||||
String tType = Object.class.getName();
|
||||
|
||||
if (resolver != null)
|
||||
tType = resolver.resolve(definedType);
|
||||
else
|
||||
try {
|
||||
tType = getDataType(db, definedType.getType(), definedType.getPrecision(), definedType.getScale())
|
||||
.getType()
|
||||
.getName();
|
||||
}
|
||||
catch (SQLDialectNotSupportedException ignore) {}
|
||||
|
||||
String tType = tType(db, resolver, definedType);
|
||||
converter = "new " + EnumConverter.class.getName() + "<" + tType + ", " + uType + ">(" + tType + ".class, " + uType + ".class)";
|
||||
}
|
||||
else if (customType.getLambdaConverter() != null) {
|
||||
LambdaConverter c = customType.getLambdaConverter();
|
||||
String tType = tType(db, resolver, definedType);
|
||||
converter = "org.jooq.Converter.of" + (!FALSE.equals(c.isNullable()) ? "Nullable" : "") + "(" + tType + ".class, " + uType + ".class, " + c.getFrom() + ", " + c.getTo() + ")";
|
||||
}
|
||||
else if (!StringUtils.isBlank(customType.getConverter())) {
|
||||
converter = customType.getConverter();
|
||||
}
|
||||
@ -309,6 +304,20 @@ public abstract class AbstractTypedElementDefinition<T extends Definition>
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final String tType(Database db, JavaTypeResolver resolver, DataTypeDefinition definedType) {
|
||||
if (resolver != null)
|
||||
return resolver.resolve(definedType);
|
||||
|
||||
try {
|
||||
return getDataType(db, definedType.getType(), definedType.getPrecision(), definedType.getScale())
|
||||
.getType()
|
||||
.getName();
|
||||
}
|
||||
catch (SQLDialectNotSupportedException ignore) {
|
||||
return Object.class.getName();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static final CustomType customType(Database db, ForcedType forcedType) {
|
||||
String name = forcedType.getName();
|
||||
@ -328,6 +337,7 @@ public abstract class AbstractTypedElementDefinition<T extends Definition>
|
||||
return new CustomType()
|
||||
.withBinding(forcedType.getBinding())
|
||||
.withEnumConverter(forcedType.isEnumConverter())
|
||||
.withLambdaConverter(forcedType.getLambdaConverter())
|
||||
.withConverter(forcedType.getConverter())
|
||||
.withName(name)
|
||||
.withType(forcedType.getUserType());
|
||||
|
||||
@ -38,6 +38,7 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String converter;
|
||||
protected Boolean enumConverter;
|
||||
protected LambdaConverter lambdaConverter;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String binding;
|
||||
|
||||
@ -121,6 +122,24 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
this.enumConverter = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use ForcedType only
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public LambdaConverter getLambdaConverter() {
|
||||
return lambdaConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use ForcedType only
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public void setLambdaConverter(LambdaConverter value) {
|
||||
this.lambdaConverter = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use ForcedType only
|
||||
*
|
||||
@ -174,6 +193,16 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use ForcedType only
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public CustomType withLambdaConverter(LambdaConverter value) {
|
||||
setLambdaConverter(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use ForcedType only
|
||||
*
|
||||
@ -190,6 +219,7 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
builder.append("type", type);
|
||||
builder.append("converter", converter);
|
||||
builder.append("enumConverter", enumConverter);
|
||||
builder.append("lambdaConverter", lambdaConverter);
|
||||
builder.append("binding", binding);
|
||||
}
|
||||
|
||||
@ -248,6 +278,15 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (lambdaConverter == null) {
|
||||
if (other.lambdaConverter!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!lambdaConverter.equals(other.lambdaConverter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (binding == null) {
|
||||
if (other.binding!= null) {
|
||||
return false;
|
||||
@ -268,6 +307,7 @@ public class CustomType implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((type == null)? 0 :type.hashCode()));
|
||||
result = ((prime*result)+((converter == null)? 0 :converter.hashCode()));
|
||||
result = ((prime*result)+((enumConverter == null)? 0 :enumConverter.hashCode()));
|
||||
result = ((prime*result)+((lambdaConverter == null)? 0 :lambdaConverter.hashCode()));
|
||||
result = ((prime*result)+((binding == null)? 0 :binding.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String converter;
|
||||
protected Boolean enumConverter;
|
||||
protected LambdaConverter lambdaConverter;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String binding;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
@ -140,6 +141,22 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
this.enumConverter = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A lambda converter implementation for the {@link #getUserType()}.
|
||||
*
|
||||
*/
|
||||
public LambdaConverter getLambdaConverter() {
|
||||
return lambdaConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* A lambda converter implementation for the {@link #getUserType()}.
|
||||
*
|
||||
*/
|
||||
public void setLambdaConverter(LambdaConverter value) {
|
||||
this.lambdaConverter = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link org.jooq.Binding} implementation for the custom type.
|
||||
*
|
||||
@ -365,6 +382,15 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A lambda converter implementation for the {@link #getUserType()}.
|
||||
*
|
||||
*/
|
||||
public ForcedType withLambdaConverter(LambdaConverter value) {
|
||||
setLambdaConverter(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link org.jooq.Binding} implementation for the custom type.
|
||||
*
|
||||
@ -477,6 +503,7 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
builder.append("userType", userType);
|
||||
builder.append("converter", converter);
|
||||
builder.append("enumConverter", enumConverter);
|
||||
builder.append("lambdaConverter", lambdaConverter);
|
||||
builder.append("binding", binding);
|
||||
builder.append("excludeExpression", excludeExpression);
|
||||
builder.append("includeExpression", includeExpression);
|
||||
@ -545,6 +572,15 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (lambdaConverter == null) {
|
||||
if (other.lambdaConverter!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!lambdaConverter.equals(other.lambdaConverter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (binding == null) {
|
||||
if (other.binding!= null) {
|
||||
return false;
|
||||
@ -655,6 +691,7 @@ public class ForcedType implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((userType == null)? 0 :userType.hashCode()));
|
||||
result = ((prime*result)+((converter == null)? 0 :converter.hashCode()));
|
||||
result = ((prime*result)+((enumConverter == null)? 0 :enumConverter.hashCode()));
|
||||
result = ((prime*result)+((lambdaConverter == null)? 0 :lambdaConverter.hashCode()));
|
||||
result = ((prime*result)+((binding == null)? 0 :binding.hashCode()));
|
||||
result = ((prime*result)+((excludeExpression == null)? 0 :excludeExpression.hashCode()));
|
||||
result = ((prime*result)+((includeExpression == null)? 0 :includeExpression.hashCode()));
|
||||
|
||||
186
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/LambdaConverter.java
Normal file
186
jOOQ-meta/src/main/java/org/jooq/meta/jaxb/LambdaConverter.java
Normal file
@ -0,0 +1,186 @@
|
||||
|
||||
package org.jooq.meta.jaxb;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import org.jooq.util.jaxb.tools.StringAdapter;
|
||||
import org.jooq.util.jaxb.tools.XMLAppendable;
|
||||
import org.jooq.util.jaxb.tools.XMLBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* A converter taking two lambda definitions.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "LambdaConverter", propOrder = {
|
||||
|
||||
})
|
||||
@SuppressWarnings({
|
||||
"all"
|
||||
})
|
||||
public class LambdaConverter implements Serializable, XMLAppendable
|
||||
{
|
||||
|
||||
private final static long serialVersionUID = 31400L;
|
||||
@XmlElement(required = true)
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String from;
|
||||
@XmlElement(required = true)
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String to;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean nullable = true;
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#from(Object)}.
|
||||
*
|
||||
*/
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#from(Object)}.
|
||||
*
|
||||
*/
|
||||
public void setFrom(String value) {
|
||||
this.from = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#to(Object)}.
|
||||
*
|
||||
*/
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#to(Object)}.
|
||||
*
|
||||
*/
|
||||
public void setTo(String value) {
|
||||
this.to = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use {@link org.jooq.Converter#ofNullable(Class, Class, java.util.function.Function, java.util.function.Function)} or {@link org.jooq.Converter#of(Class, Class, java.util.function.Function, java.util.function.Function)}.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the nullable property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setNullable(Boolean value) {
|
||||
this.nullable = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#from(Object)}.
|
||||
*
|
||||
*/
|
||||
public LambdaConverter withFrom(String value) {
|
||||
setFrom(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The implementation of {@link org.jooq.Converter#to(Object)}.
|
||||
*
|
||||
*/
|
||||
public LambdaConverter withTo(String value) {
|
||||
setTo(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaConverter withNullable(Boolean value) {
|
||||
setNullable(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void appendTo(XMLBuilder builder) {
|
||||
builder.append("from", from);
|
||||
builder.append("to", to);
|
||||
builder.append("nullable", nullable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
XMLBuilder builder = XMLBuilder.nonFormatting();
|
||||
appendTo(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass()!= that.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LambdaConverter other = ((LambdaConverter) that);
|
||||
if (from == null) {
|
||||
if (other.from!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!from.equals(other.from)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (to == null) {
|
||||
if (other.to!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!to.equals(other.to)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (nullable == null) {
|
||||
if (other.nullable!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!nullable.equals(other.nullable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = ((prime*result)+((from == null)? 0 :from.hashCode()));
|
||||
result = ((prime*result)+((to == null)? 0 :to.hashCode()));
|
||||
result = ((prime*result)+((nullable == null)? 0 :nullable.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@ -213,6 +213,14 @@ public class ObjectFactory {
|
||||
return new ForcedType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link LambdaConverter }
|
||||
*
|
||||
*/
|
||||
public LambdaConverter createLambdaConverter() {
|
||||
return new LambdaConverter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Generate }
|
||||
*
|
||||
|
||||
@ -1042,6 +1042,18 @@ for Oracle.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</appinfo>
|
||||
</annotation>
|
||||
</element>
|
||||
|
||||
<element name="lambdaConverter" type="tns:LambdaConverter" minOccurs="0" maxOccurs="1">
|
||||
<annotation>
|
||||
<appinfo>
|
||||
<jxb:property>
|
||||
<jxb:javadoc><![CDATA[@deprecated Use ForcedType only]]></jxb:javadoc>
|
||||
</jxb:property>
|
||||
<annox:annotate target="getter">@java.lang.Deprecated</annox:annotate>
|
||||
<annox:annotate target="setter">@java.lang.Deprecated</annox:annotate>
|
||||
</appinfo>
|
||||
</annotation>
|
||||
</element>
|
||||
|
||||
<element name="binding" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation>
|
||||
@ -1145,6 +1157,10 @@ or {@link #getBinding()} is required]]></jxb:javadoc></jxb:property></appinfo></
|
||||
<element name="enumConverter" type="boolean" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether the converter is an {@link org.jooq.impl.EnumConverter}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="lambdaConverter" type="tns:LambdaConverter" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A lambda converter implementation for the {@link #getUserType()}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="binding" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A {@link org.jooq.Binding} implementation for the custom type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
@ -1199,6 +1215,23 @@ type. If provided, both "includeExpression" and "includeTypes" must match.]]></j
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LambdaConverter">
|
||||
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[A converter taking two lambda definitions.]]></jxb:javadoc></jxb:class></appinfo></annotation>
|
||||
<all>
|
||||
<element name="from" type="string" minOccurs="1" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The implementation of {@link org.jooq.Converter#from(Object)}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="to" type="string" minOccurs="1" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The implementation of {@link org.jooq.Converter#to(Object)}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="nullable" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether to use {@link org.jooq.Converter#ofNullable(Class, Class, java.util.function.Function, java.util.function.Function)} or {@link org.jooq.Converter#of(Class, Class, java.util.function.Function, java.util.function.Function)}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="ForcedTypeObjectType">
|
||||
<restriction base="string">
|
||||
<enumeration value="ALL"/>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user