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.

4
  • 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) Commented Jun 9, 2016 at 13:37
  • Possible duplicate of Java - Creating an array of methods Commented Jun 9, 2016 at 13:37
  • @MatheM I took a look at that question, but it did not quite work with my situation. Commented Jun 9, 2016 at 14:04
  • @ArturBiesiadowski unfortunately I am using java 7, but will definitely have a look at XML processing APIs thanks. Commented Jun 9, 2016 at 14:05

1 Answer 1

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
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.