1

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.

Community
  • 1
  • 1
Hendrien
  • 315
  • 1
  • 10
  • 19
  • 4
    If you are using java 8, you can have map of String -> SomeInterface, with SomeInterface having `void accept(Node node);` method and then fill out it with things like `map.put("maximumRedeliveries", this::setMaximumRedeliveries);` Said that, there is plenty of XML processing APIs which can do it in more maintainable way (by putting data directly into pojos generated from schema, into your pojos, by allowing you to query values explicitly instead of reacting to them, etc etc) – Artur Biesiadowski Jun 09 '16 at 13:37
  • Possible duplicate of [Java - Creating an array of methods](http://stackoverflow.com/questions/4280727/java-creating-an-array-of-methods) – MatheM Jun 09 '16 at 13:37
  • @MatheM I took a look at that question, but it did not quite work with my situation. – Hendrien Jun 09 '16 at 14:04
  • @ArturBiesiadowski unfortunately I am using java 7, but will definitely have a look at XML processing APIs thanks. – Hendrien Jun 09 '16 at 14:05

1 Answers1

1

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
}
Community
  • 1
  • 1
Sergey Kalinichenko
  • 697,062
  • 78
  • 1,055
  • 1,465