Hendrien
Hendrien

Reputation: 345

Array of set methods - Java

I am busy with a project that extracts data from a xml file and displays it in a word document. I have created a method for this extraction, but I want to simplify it by using an array of methods. This is just an example of how I test for certain information at the moment:

for (int i = 0; i < nodeMap.getLength(); i++) {
    Node node = nodeMap.item(i);
 if (node.getNodeName().equalsIgnoreCase("maximumRedeliveries")) {

   if (node.getNodeValue().startsWith("{{")) {
       retryLogic.setMaximumRedeliveries(extractPropertyName(node.getNodeValue(), propFileLocation));
   } else {
       retryLogic.setMaximumRedeliveries(node.getNodeValue());
     }
 }
 if (node.getNodeName().equalsIgnoreCase("asyncDelayedRedelivery")) {

   if (node.getNodeValue().startsWith("{{")) {
       retryLogic.setAsyncDelayedRedelivery(extractPropertyName(node.getNodeValue(), propFileLocation));
   } else {
       retryLogic.setAsyncDelayedRedelivery(node.getNodeValue());
     }
  }
}

I am aiming to create an array for the if statement values, for example "maximumRedeliveries" and "asyncDelayedRedelivery" and an array for their corresponding methods, for example setMaximumRedeliveries(),setAsyncDelayedRedelivery(). I am unsure of how to create an array of methods, or if it's even possible?

This problem differs form Java - Creating an array of methods, because I use set methods and don't know how to implement it in that way.

Upvotes: 1

Views: 186

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726539

First, ensure that extractPropertyName takes names with and without curly braces, and behaves like this:

String extractOptionalPropertyName(String name, String propFileLocation) {
    return name..startsWith("{{") ? extractPropertyName(name, propFileLocation) : name;
}

This moves conditionals from your XML processing code into a helper:

String nodeName = node.getNodeName();
if (nodeName.equalsIgnoreCase("maximumRedeliveries")) {
    retryLogic.setMaximumRedeliveries(extractOptionalPropertyName(node.getNodeValue(), propFileLocation));
} else if (nodeName.equalsIgnoreCase("asyncDelayedRedelivery")) {
    retryLogic.setAsyncDelayedRedelivery(extractOptionalPropertyName(node.getNodeValue(), propFileLocation));
} ... // and so on

With these changes in place, you can follow the recipe from this other Q&A and make a Map<String,ValSetter> objects, like this:

interface ValSetter {
    void set(RetryLogic logic, String val);
}
// The map can be made static in a class
Map<String,ValSetter> setterForName = new HashMap<>();
{ // Initializer block
    setterForName.put("maximumredeliveries", new ValSetter() {public void set(RetryLogic logic, String val) { logic.setMaximumRedeliveries(val);}} );
    setterForName.put("asyncrelayedredelivery", new ValSetter() {public void set(RetryLogic logic, String val) { logic.setAsyncDelayedRedelivery(val);}} );
}

Now your XML handler could look like this:

String nodeName = node.getNodeName();
ValSetter setter = setterForName.get(nodeName.toLowerCase());
if (setter != null) {
    String val = extractOptionalPropertyName(node.getNodeValue(), propFileLocation);
    setter.set(retryLogic, val);
} else {
    // report an error
}

Upvotes: 1

Related Questions