I don't think Digester supports this natively, but I can suggest a couple of options that may help to get you there.
Simplest is to just use a custom HashSet
implementation which rejects the names you don't like:
public class MyHashSet extends HashSet<Parameter> {
@Override
public boolean add(Parameter param) {
if (param != null && "Alex".equals(param.getName())) {
return false;
}
return super.add(param);
}
}
And then use this instead of the standard HashSet
in your rules:
<pattern value="input-parameters">
<object-create-rule classname="com.foo.MyHashSet"/>
<set-next-rule methodname="addParameters"/>
...
</pattern>
The main drawback I can see from this approach is that you are left with your custom hash set implementation in your resulting object, so if you later try to add a parameter with name = "Alex" directly from code it will again be rejected; this may or may not be a problem.
A slightly more complex approach would be to switch out the standard SetNextRule
with a custom implementation which checked the name before adding the parameter. The standard SetNextRule
fires on the event end, so the following rule would do the trick:
public class SetNextParamRule extends SetNextRule {
public SetNextParamRule() {
super("add");
}
@Override
public void end(String namespace, String name) throws Exception {
Parameter param = (Parameter)getChild();
if (!"Alex".equals(param.getName())) {
super.end(namespace, name);
}
}
}
One problem with this approach is that I can't see a way to add custom rules using the XML configuration (I rarely use XML config so could be wrong here), so you would need to use code configuration instead:
final Rule setNextParamRule = new SetNextParamRule();
RulesModule rules = new AbstractRulesModule() {
@Override
public void configure() {
forPattern("input-parameters")
.createObject().ofType(HashSet.class)
.then().setNext("addParameters");
forPattern("input-parameters/parameter")
.createObject().ofType(Parameter.class)
.then().addRule(setNextParamRule);
forPattern("input-parameters/parameter/name").setBeanProperty();
forPattern("input-parameters/parameter/description").setBeanProperty();
}
};
DigesterLoader loader = DigesterLoader.newLoader(rules);
Digester digester = loader.newDigester();
One advantage of this however is that you could potentially supply the list of names to ignore from a separate source:
import com.google.common.collect.ImmutableSet;
final Set<String> skipNames = ImmutableSet.of("Alex", "Adam");
final Rule setNextParamRule = new SetNextRule("add") {
@Override
public void end(String namespace, String name) throws Exception {
Parameter param = (Parameter)getChild();
if (!skipNames.contains(param.getName())) {
super.end(namespace, name);
}
}
};
// rest as above
Hope some of this helps.