[#7545] Add <includeExpression> and <excludeExpression> to <forcedType>
Add <includeExpression> and <excludeExpression> as well as <includeTypes> and <excludeTypes> to <forcedType>. The generator will warn about usage conflicting with the legacy <expression>, <expressions>, and <types> elements.
This commit is contained in:
parent
840f5a2aed
commit
adcb72fcfb
@ -1089,9 +1089,21 @@ public abstract class AbstractDatabase implements Database {
|
||||
ForcedType type = it2.next();
|
||||
|
||||
if (type.getExpressions() != null) {
|
||||
type.setExpression(type.getExpressions());
|
||||
type.setIncludeExpression(type.getExpressions());
|
||||
type.setExpressions(null);
|
||||
log.warn("DEPRECATED", "The <expressions/> element in <forcedType/> is deprecated. Use <expression/> instead: " + type);
|
||||
log.warn("DEPRECATED", "The <expressions/> element in <forcedType/> is deprecated. Use <includeExpression/> instead: " + type);
|
||||
}
|
||||
|
||||
if (type.getExpression() != null) {
|
||||
type.setIncludeExpression(type.getExpression());
|
||||
type.setExpression(null);
|
||||
log.warn("DEPRECATED", "The <expression/> element in <forcedType/> is deprecated. Use <includeExpression/> instead: " + type);
|
||||
}
|
||||
|
||||
if (type.getTypes() != null) {
|
||||
type.setIncludeTypes(type.getTypes());
|
||||
type.setTypes(null);
|
||||
log.warn("DEPRECATED", "The <types/> element in <forcedType/> is deprecated. Use <includeTypes/> instead: " + type);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(type.getName())) {
|
||||
@ -1480,8 +1492,10 @@ public abstract class AbstractDatabase implements Database {
|
||||
// [#5885] Only the first matching <forcedType/> is applied to the data type definition.
|
||||
forcedTypeLoop:
|
||||
for (ForcedType forcedType : getConfiguredForcedTypes()) {
|
||||
String expression = StringUtils.defaultIfNull(forcedType.getExpressions(), forcedType.getExpression());
|
||||
String types = forcedType.getTypes();
|
||||
String excludeExpression = forcedType.getExcludeExpression();
|
||||
String includeExpression = StringUtils.firstNonNull(forcedType.getIncludeExpression(), forcedType.getExpression(), forcedType.getExpressions());
|
||||
String excludeTypes = forcedType.getExcludeTypes();
|
||||
String includeTypes = StringUtils.firstNonNull(forcedType.getIncludeTypes(), forcedType.getTypes());
|
||||
Nullability nullability = forcedType.getNullability();
|
||||
ForcedTypeObjectType objectType = forcedType.getObjectType();
|
||||
String sql = forcedType.getSql();
|
||||
@ -1499,30 +1513,18 @@ public abstract class AbstractDatabase implements Database {
|
||||
|| (nullability == Nullability.NULL && !definedType.isNullable())))
|
||||
continue forcedTypeLoop;
|
||||
|
||||
if (expression != null)
|
||||
if (!matches(patterns.pattern(expression), definition))
|
||||
continue forcedTypeLoop;
|
||||
if ( (excludeExpression != null || includeExpression != null)
|
||||
&& filterExcludeInclude(
|
||||
Collections.singletonList(definition),
|
||||
new String[] { excludeExpression },
|
||||
new String[] { includeExpression != null ? includeExpression : ".*" },
|
||||
getFilters()
|
||||
).isEmpty())
|
||||
continue forcedTypeLoop;
|
||||
|
||||
if (types != null && definedType != null) {
|
||||
Pattern p = patterns.pattern(types);
|
||||
|
||||
if ( ( !p.matcher(definedType.getType()).matches() )
|
||||
&& ( definedType.getLength() == 0
|
||||
|| !p.matcher(definedType.getType() + "(" + definedType.getLength() + ")").matches())
|
||||
&& ( definedType.getScale() != 0
|
||||
|| !p.matcher(definedType.getType() + "(" + definedType.getPrecision() + ")").matches())
|
||||
&& ( !p.matcher(definedType.getType() + "(" + definedType.getPrecision() + "," + definedType.getScale() + ")").matches() )
|
||||
&& ( !p.matcher(definedType.getType() + "(" + definedType.getPrecision() + ", " + definedType.getScale() + ")").matches() )
|
||||
|
||||
// [#5872] We should match user-defined types as well, in case of which the type might be reported
|
||||
// as USER-DEFINED (in PostgreSQL)
|
||||
&& ( StringUtils.isBlank(definedType.getUserType())
|
||||
|| !p.matcher(definedType.getUserType()).matches()
|
||||
&& !p.matcher(definedType.getQualifiedUserType().unquotedName().toString()).matches() )
|
||||
) {
|
||||
continue forcedTypeLoop;
|
||||
}
|
||||
}
|
||||
if ( (definedType != null && (excludeTypes != null || includeTypes != null))
|
||||
&& !typeMatchesExcludeInclude(definedType, excludeTypes, includeTypes))
|
||||
continue forcedTypeLoop;
|
||||
|
||||
if (sql != null)
|
||||
if (!matches(statements.fetchSet(sql), definition))
|
||||
@ -1534,6 +1536,30 @@ public abstract class AbstractDatabase implements Database {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean typeMatchesExcludeInclude(DataTypeDefinition type, String exclude, String include) {
|
||||
if (exclude != null && matches(type, patterns.pattern(exclude)))
|
||||
return false;
|
||||
|
||||
return include == null || matches(type, patterns.pattern(include));
|
||||
}
|
||||
|
||||
private boolean matches(DataTypeDefinition type, Pattern pattern) {
|
||||
return ( pattern.matcher(type.getType()).matches() )
|
||||
|| ( type.getLength() != 0
|
||||
&& pattern.matcher(type.getType() + "(" + type.getLength() + ")").matches() )
|
||||
|| ( type.getScale() == 0
|
||||
&& pattern.matcher(type.getType() + "(" + type.getPrecision() + ")").matches() )
|
||||
|| ( pattern.matcher(type.getType() + "(" + type.getPrecision() + "," + type.getScale() + ")").matches() )
|
||||
|| ( pattern.matcher(type.getType() + "(" + type.getPrecision() + ", " + type.getScale() + ")").matches() )
|
||||
|
||||
// [#5872] We should match user-defined types as well, in case of which the type might be reported
|
||||
// as USER-DEFINED (in PostgreSQL)
|
||||
|| ( !StringUtils.isBlank(type.getUserType())
|
||||
&& ( pattern.matcher(type.getUserType()).matches()
|
||||
|| pattern.matcher(type.getQualifiedUserType().unquotedName().toString()).matches() )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setConfiguredEmbeddables(List<Embeddable> configuredEmbeddables) {
|
||||
this.configuredEmbeddables = configuredEmbeddables;
|
||||
|
||||
@ -45,12 +45,20 @@ public class ForcedType implements Serializable
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String binding;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String excludeExpression;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String includeExpression;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String expression;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String expressions;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String sql;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String excludeTypes;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String includeTypes;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String types;
|
||||
@XmlElement(defaultValue = "ALL")
|
||||
@XmlSchemaType(name = "string")
|
||||
@ -184,8 +192,58 @@ public class ForcedType implements Serializable
|
||||
|
||||
/**
|
||||
* A Java regular expression matching columns, parameters, attributes,
|
||||
* etc to be forced to have this type. If provided, both "expressions" and
|
||||
* "types" must match.
|
||||
* etc. which must not have this type. Excludes match before includes, i.e.
|
||||
* excludes have a higher priority.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getExcludeExpression() {
|
||||
return excludeExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the excludeExpression property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setExcludeExpression(String value) {
|
||||
this.excludeExpression = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Java regular expression matching columns, parameters, attributes,
|
||||
* etc. to be forced to have this type. If provided, both "includeExpression" and
|
||||
* "includeTypes" must match.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getIncludeExpression() {
|
||||
return includeExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the includeExpression property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setIncludeExpression(String value) {
|
||||
this.includeExpression = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #getIncludeExpression()}. This is kept for backwards compatibility reasons.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
@ -209,7 +267,7 @@ public class ForcedType implements Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as expression. This is kept for backwards compatibility reasons.
|
||||
* The same as {@link #getIncludeExpression()}. This is kept for backwards compatibility reasons.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
@ -256,9 +314,59 @@ public class ForcedType implements Serializable
|
||||
this.sql = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Java regular expression matching data types
|
||||
* which must not have this type. Excludes match before includes, i.e.
|
||||
* excludes have a higher priority.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getExcludeTypes() {
|
||||
return excludeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the excludeTypes property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setExcludeTypes(String value) {
|
||||
this.excludeTypes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Java regular expression matching data types to be forced to have this
|
||||
* type. If provided, both "expression" and "types" must match.
|
||||
* type. If provided, both "includeExpression" and "includeTypes" must match.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getIncludeTypes() {
|
||||
return includeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the includeTypes property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setIncludeTypes(String value) {
|
||||
this.includeTypes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as {@link #getIncludeTypes()}. This is kept for backwards compatibility reasons.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
@ -354,6 +462,16 @@ public class ForcedType implements Serializable
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withExcludeExpression(String value) {
|
||||
setExcludeExpression(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withIncludeExpression(String value) {
|
||||
setIncludeExpression(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withExpression(String value) {
|
||||
setExpression(value);
|
||||
return this;
|
||||
@ -369,6 +487,16 @@ public class ForcedType implements Serializable
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withExcludeTypes(String value) {
|
||||
setExcludeTypes(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withIncludeTypes(String value) {
|
||||
setIncludeTypes(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ForcedType withTypes(String value) {
|
||||
setTypes(value);
|
||||
return this;
|
||||
@ -412,6 +540,16 @@ public class ForcedType implements Serializable
|
||||
sb.append(binding);
|
||||
sb.append("</binding>");
|
||||
}
|
||||
if ((excludeExpression!= null)&&(!"".equals(excludeExpression))) {
|
||||
sb.append("<excludeExpression>");
|
||||
sb.append(excludeExpression);
|
||||
sb.append("</excludeExpression>");
|
||||
}
|
||||
if ((includeExpression!= null)&&(!"".equals(includeExpression))) {
|
||||
sb.append("<includeExpression>");
|
||||
sb.append(includeExpression);
|
||||
sb.append("</includeExpression>");
|
||||
}
|
||||
if ((expression!= null)&&(!"".equals(expression))) {
|
||||
sb.append("<expression>");
|
||||
sb.append(expression);
|
||||
@ -427,6 +565,16 @@ public class ForcedType implements Serializable
|
||||
sb.append(sql);
|
||||
sb.append("</sql>");
|
||||
}
|
||||
if ((excludeTypes!= null)&&(!"".equals(excludeTypes))) {
|
||||
sb.append("<excludeTypes>");
|
||||
sb.append(excludeTypes);
|
||||
sb.append("</excludeTypes>");
|
||||
}
|
||||
if ((includeTypes!= null)&&(!"".equals(includeTypes))) {
|
||||
sb.append("<includeTypes>");
|
||||
sb.append(includeTypes);
|
||||
sb.append("</includeTypes>");
|
||||
}
|
||||
if ((types!= null)&&(!"".equals(types))) {
|
||||
sb.append("<types>");
|
||||
sb.append(types);
|
||||
@ -502,6 +650,24 @@ public class ForcedType implements Serializable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (excludeExpression == null) {
|
||||
if (other.excludeExpression!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!excludeExpression.equals(other.excludeExpression)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (includeExpression == null) {
|
||||
if (other.includeExpression!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!includeExpression.equals(other.includeExpression)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (expression == null) {
|
||||
if (other.expression!= null) {
|
||||
return false;
|
||||
@ -529,6 +695,24 @@ public class ForcedType implements Serializable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (excludeTypes == null) {
|
||||
if (other.excludeTypes!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!excludeTypes.equals(other.excludeTypes)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (includeTypes == null) {
|
||||
if (other.includeTypes!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!includeTypes.equals(other.includeTypes)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (types == null) {
|
||||
if (other.types!= null) {
|
||||
return false;
|
||||
@ -568,9 +752,13 @@ public class ForcedType implements Serializable
|
||||
result = ((prime*result)+((converter == null)? 0 :converter.hashCode()));
|
||||
result = ((prime*result)+((enumConverter == null)? 0 :enumConverter.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()));
|
||||
result = ((prime*result)+((expression == null)? 0 :expression.hashCode()));
|
||||
result = ((prime*result)+((expressions == null)? 0 :expressions.hashCode()));
|
||||
result = ((prime*result)+((sql == null)? 0 :sql.hashCode()));
|
||||
result = ((prime*result)+((excludeTypes == null)? 0 :excludeTypes.hashCode()));
|
||||
result = ((prime*result)+((includeTypes == null)? 0 :includeTypes.hashCode()));
|
||||
result = ((prime*result)+((types == null)? 0 :types.hashCode()));
|
||||
result = ((prime*result)+((nullability == null)? 0 :nullability.hashCode()));
|
||||
result = ((prime*result)+((objectType == null)? 0 :objectType.hashCode()));
|
||||
|
||||
@ -40,7 +40,7 @@ public class MatchersEnumType implements Serializable
|
||||
protected String enumImplements;
|
||||
|
||||
/**
|
||||
* This sequence matcher applies to all unqualified or qualified enum names matched by this expression. If left empty, this matcher applies to all enums.
|
||||
* This enum matcher applies to all unqualified or qualified enum names matched by this expression. If left empty, this matcher applies to all enums.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
|
||||
@ -344,7 +344,7 @@
|
||||
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[Declarative naming strategy configuration for enum names.]]></jxb:javadoc></jxb:class></appinfo></annotation>
|
||||
<all>
|
||||
<element name="expression" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This sequence matcher applies to all unqualified or qualified enum names matched by this expression. If left empty, this matcher applies to all enums.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This enum matcher applies to all unqualified or qualified enum names matched by this expression. If left empty, this matcher applies to all enums.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="enumClass" type="tns:MatcherRule" minOccurs="0" maxOccurs="1">
|
||||
@ -935,23 +935,43 @@ or {@link #getBinding()} is required]]></jxb:javadoc></jxb:property></appinfo></
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A {@link org.jooq.Binding} implementation for the custom type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="expression" type="string" minOccurs="0" maxOccurs="1">
|
||||
<element name="excludeExpression" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A Java regular expression matching columns, parameters, attributes,
|
||||
etc to be forced to have this type. If provided, both "expressions" and
|
||||
"types" must match.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
etc. which must not have this type. Excludes match before includes, i.e.
|
||||
excludes have a higher priority.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="includeExpression" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A Java regular expression matching columns, parameters, attributes,
|
||||
etc. to be forced to have this type. If provided, both "includeExpression" and
|
||||
"includeTypes" must match.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="expression" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The same as {@link #getIncludeExpression()}. This is kept for backwards compatibility reasons.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="expressions" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The same as expression. This is kept for backwards compatibility reasons.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The same as {@link #getIncludeExpression()}. This is kept for backwards compatibility reasons.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="sql" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A SQL statement that produces a table with one column containing the matched qualified or unqualified column names.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="types" type="string" minOccurs="0" maxOccurs="1">
|
||||
<element name="excludeTypes" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A Java regular expression matching data types
|
||||
which must not have this type. Excludes match before includes, i.e.
|
||||
excludes have a higher priority.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="includeTypes" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A Java regular expression matching data types to be forced to have this
|
||||
type. If provided, both "expression" and "types" must match.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
type. If provided, both "includeExpression" and "includeTypes" must match.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="types" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The same as {@link #getIncludeTypes()}. This is kept for backwards compatibility reasons.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="nullability" type="tns:Nullability" default="ALL" minOccurs="0" maxOccurs="1">
|
||||
|
||||
@ -1302,6 +1302,22 @@ public final class StringUtils {
|
||||
return object != null ? object : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the first non-{@code null} argument.</p>
|
||||
*
|
||||
* @param <T> the type of the objects
|
||||
* @param objects the elements to test, may not be {@code null} but empty
|
||||
* @return first non-{@code null} element in {@code objects}, otherwise {@code null}
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <T> T firstNonNull(T... objects) {
|
||||
for (T object : objects) {
|
||||
if (object != null)
|
||||
return object;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: The following methods are not part of Apache's commons-lang library
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user