I am currently reworking our entity code generator, that uses JaxB for schema validation, and Stringtemplate for code generation.
As we are giving our professional service the possibility to add Validators to the attributes of the entities they create, I need to wrap each parsed Field, in order to add the Validators.
The following code works, but I do not feel comfortable with it:
@SuppressWarnings( "boxing" )
private Map<String, Object> wrapField( Field f )
{
HashMap<String, Object> result = new HashMap<>();
if ( f.isGenerateGetter() )
{
DecimalMaxValidator decMax = null;
DecimalMinValidator decMin = null;
NotBlankValidator notBlank = null;
NotNullValidator notNull = null;
LengthValidator lengthVal = null;
result.put( "generateGetters", f.isGenerateGetter() );
result.put( "getterAddOverride", f.isGetterAddOverride() );
for ( Validator v : f.getValidators().getValidators() )
{
HashMap<String, Object> tmp = new HashMap<>();
if ( v instanceof DecimalMaxValidator )
{
decMax = addDecimalMaxValidator( result, decMax, v, tmp );
}
else if ( v instanceof DecimalMinValidator )
{
decMin = addDecimalMinValidator( result, decMin, v, tmp );
}
else if ( v instanceof NotBlankValidator )
{
notBlank = addNotBlankValidator( notBlank, v, tmp );
}
else if ( v instanceof NotNullValidator )
{
notNull = addNotNullValidator( notNull, v, tmp );
}
else if ( v instanceof LengthValidator )
{
lengthVal = addLengthValidator( lengthVal, v, tmp );
}
else
{
// TODO: error: Wrong type? type not found?
}
}
}
return result;
}
private NotNullValidator addNotNullValidator( NotNullValidator notNull, Validator v, HashMap<String, Object> tmp )
{
if ( notNull == null )
{
notNull = (NotNullValidator) v;
tmp.put( "notNullValidator", true );
tmp.put( "notBlankValidatorTransKey", v.getTranslationKey() );
}
else
{
// TODO error: double dec
}
return notNull;
}
@SuppressWarnings( "boxing" )
private NotBlankValidator addNotBlankValidator( NotBlankValidator notBlank, Validator v, HashMap<String, Object> tmp )
{
if ( notBlank == null )
{
notBlank = (NotBlankValidator) v;
tmp.put( "notBlankValidator", true );
tmp.put( "notBlankValidatorTransKey", v.getTranslationKey() );
}
else
{
// TODO error, double dec
}
return notBlank;
}
@SuppressWarnings( "boxing" )
private DecimalMinValidator addDecimalMinValidator( HashMap<String, Object> result, DecimalMinValidator decMin, Validator v,
HashMap<String, Object> tmp )
{
if ( decMin == null )
{
decMin = (DecimalMinValidator) v;
tmp.put( "value", decMin.getValue() );
tmp.put( "inclusive", decMin.isInclusive() );
tmp.put( "translationKey", decMin.getTranslationKey() );
result.put( "decimalMinValidator", tmp );
}
else
{
// TODO error, double dec
}
return decMin;
}
@SuppressWarnings( "boxing" )
private DecimalMaxValidator addDecimalMaxValidator( HashMap<String, Object> result, DecimalMaxValidator decMax, Validator v,
HashMap<String, Object> tmp )
{
if ( decMax == null )
{
decMax = (DecimalMaxValidator) v;
tmp.put( "value", decMax.getValue() );
tmp.put( "inclusive", decMax.isInclusive() );
tmp.put( "translationKey", decMax.getTranslationKey() );
result.put( "decimalMaxValidator", tmp );
}
else
{
// TODO error, double dec
}
return decMax;
}
private LengthValidator addLengthValidator( LengthValidator lengthVal, Validator v, HashMap<String, Object> tmp )
{
if ( lengthVal == null )
{
lengthVal = (LengthValidator) v;
tmp.put( "min", lengthVal.getMin() );
tmp.put( "max", lengthVal.getMax() );
tmp.put( "translationKey", lengthVal.getTranslationKey() );
}
else
{
// TODO error, double dec
}
return lengthVal;
}
There are no explanations yet, but the code should be mostly self-explanatory.
Comparing the outsourced addXXXValidator
methods, feels awkward regarding redundant code.
As I am not very familiar with the java generics, I need your help with refatoring this code, so it gets smaller, faster and better maintainable.
How can I make the addXXXValidator
methods more "beautiful"?
Note:
I am not allowed to edit the Validator classes.
Explanation to the getValidators()
call:
f.getValidators() // Wrapper, returns a Validators object
.getValidators() // "second call", returns a List of Validator objects
while there is the Validators object: (the types are our internal types)
<complexType name="validatorsType">
<complexContent>
<restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
<choice maxOccurs="unbounded" minOccurs="0">
<element name="notNullValidator" type="notNullValidatorType"/>
<element name="notBlankValidator" type="notBlankValidatorType"/>
<element name="decimalMaxValidator" type="decimalMaxValidatorType"/>
<element name="decimalMinValidator" type="decimalMinValidatorType"/>
<element name="lengthValidator" type="lengthValidatorType"/>
<element name="patternValidator" type="patternValidatorType"/>
</choice>
</restriction>
</complexContent>
</complexType>
and the Validator class:
<complexType name="validatorType">
<complexContent>
<restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
<attribute name="translationKey" type="{http://www.w3.org/2001/XMLSchema}string" />
</restriction>
</complexContent>
</complexType>
The NotNullValidator :
<complexType name="notNullValidatorType">
<complexContent>
<extension base="validatorType">
</extension>
</complexContent>
</complexType>
The DecimalMaxValidator :
<complexType name="decimalMaxValidatorType">
<complexContent>
<extension base="validatorType">
<attribute name="value" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
<attribute name="inclusive" type="boolean" default="true" />
</extension>
</complexContent>
</complexType>
The DecimalMinValidator is similar to DecimalMaxV. The NotBlankV similar to NotNullV.
The LengthValidator:
<complexType name="lengthValidatorType">
<complexContent>
<extension base="validatorType">
<attribute name="min" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
<attribute name="max" type="{http://www.w3.org/2001/XMLSchema}integer" default="2147483647" />
</extension>
</complexContent>
</complexType>
While the above Schemafragments represent the
Expected content of the class (taken from the class documentation)
decMax = addDecimalMaxValidator( result, decMax, v, result);
in eachwrapField
else if? \$\endgroup\$ – MrBrushy Jan 18 '17 at 15:12field.getValidators()
return? It could be interesting. If its a custom validators holder object, it might hold the key to the solution. There is code lacking, would you mind sharing it? I don't like guessing too much. \$\endgroup\$ – MrBrushy Jan 18 '17 at 15:23decMax, decMin, notBlank etc.
to the return values of the outsourced functions. I will update the question in order to share the meaning ofgetValidators()
\$\endgroup\$ – Do Re Jan 18 '17 at 15:38