It would work fine if the attribute wasn´t sometimes "", aka empty.
This is not correct here: The attributes value - seen as string - is not empty in the meaning of missing or "nothing", it's an empty string.
Here's an example:
XML:
<root value=""></root>
Java class:
@Root(name = "root")
public class Example
{
@Attribute(name = "value", empty = "-1", required = false)
private long value;
@Override
public String toString()
{
return "Example{" + "value=" + value + '}';
}
}
This throws - and that's reasonable - a NumberFormatException
. If you replace the type of value
with String
you wont catch an exception, value is set as an empty string (""
). On the other hand, keeping string type but removing the attribute in XML will set "-1"
as value (that's why required = false
is used). Now the Serializer can't find any value and therefore sets the default one.
You could handle this in your class internally, like let the corresponding getter-method return -1
in case of an empty string:
public long getValue()
{
if( value == null || value.isEmpty() == true )
{
return -1;
}
return Long.valueOf(value);
}
(Don't forget to change your code according this - in my example you have to change toString()
-method)
But there's a better solution: Simple allows you to implement custom Transformer for any types (don't mix with Converter
!). With these you can implement type -> String
(write) and String -> type
(read) as you need.
Based on my example above, here's an implementation:
public class LongTransformer implements Transform<Long>
{
// Default value which is set if no / empty input is available
private final long defaultValue;
public LongTransformer(long defaultValue)
{
this.defaultValue = defaultValue;
}
public LongTransformer()
{
this(-1); // Just in case you always have -1 as default
}
@Override
public Long read(String value) throws Exception
{
// If there's no or an empty String the default value is returned
if( value == null || value.isEmpty() == true )
{
return defaultValue; //
}
return Long.valueOf(value); // Return the value
}
@Override
public String write(Long value) throws Exception
{
/*
* Nothing special here. In case you you need a empty string if
* value = -1, you can do it here.
*/
return value.toString();
}
}
And finally a example how to use. The key parts are between the two lines:
final String xml = "<root value=\"\">\n"
+ "</root>";
// ---------------------------------------------------------------------
final LongTransformer numberTransformer = new LongTransformer(-1);
RegistryMatcher m = new RegistryMatcher();
m.bind(long.class, numberTransformer);
Serializer ser = new Persister(m);
// ---------------------------------------------------------------------
Example root = ser.read(Example.class, xml);
System.out.println(root);
Output:
Example{value=-1}