A qu. of style: dynamic map JSTL hack to work around missing parameter function calls

456 views Asked by At

This is not a problem that needs a solution but a question to the experienced developer (hope such things are allowed here too..) about how they judge this proposal.

In JSP/JSTL you can only "call" pure getters (without parameters), i.e. properties. This probably has good reasons (by the way - what would these be..?)

But in everyday work this can be quite limitating. Often you wish you could give some simple Parameter to some getter, just because you need it. What you have to do then is to pre-calculate the data: pre-run all of the "logic" (with forEach and if) of the page in the Java code, create some new wrapper class (only for some very specific thing) and maybe create data structures of them.

Very much work, very laborious, very annoying. For the lazy of us. Am I lazy? May be. Isnt there that old saying that coders are lazy by nature, and thats their incentive for finding interesting new ideas?

OK, here is my hack. I am very curious what you think of it. My project leader does not like it at all..

I have a Map implementation DynamicMap that does not just supply some previously stored values, but get() runs a function, passing in the key and giving out the result as value. The function must be provided by an object implementing DynamicMapCalculator's call(). (the rest of the map methods return some feasible default values like size 1, empty is false etc - not so important) (*)

public class DynamicMap<K, V> implements Map<K, V>
{
  private final DynamicMapCalculator<K, V> calculator;
  public DynamicMap(final DynamicMapCalculator<K, V> calculator)
  {
    this.calculator = calculator;
  }
  public V get(final Object key)
  {
    return calculator.call(key);
  }
}

public interface DynamicMapCalculator<K, V>
{
  public V call(Object key);
}

Now, in an entity we can give out a map via a getter:

public DynamicMap<Node, String> getPathBelowDynMap()
{
  return new DynamicMap<Node, String>(new DynamicMapCalculator<Node, String>()
  {
    private Node node;

    public DynamicMapCalculator<Node, String> init(final Node node)
    {
      this.node = node;
      return this;
    }

    public String call(final Object key)
    {
      return node.getPathBelow((Node) key); // some parent node we want the relative path of this node below
    }
  }.init(this));
}

So, you create an instance implementing the DynamicMapCalculator interface using an anonymous class, passing in the calculator object (this) to an init method (can be built as needed and must return the instance itself, the "inner this") and implementing call() using some method of that object.

So now for the JSP, the reason we did all of this, where access using [] to a map is possible. It's very simple here:

<c:forEach var="node" items="${myNodeList}">
  <li><c:out value="${node.pathBelowDynMap[someParentNode]}"/></li>
</c:forEach>

Well, I find this sophisticated and elegant. Now, crush me.. but with good reasons and good explanations why this is sooo baaaad, please. Of course, I would prefer if you would give me good reasons why this is perfectly OK to do. And sophisticated. And elegant. :)

Thanks for your attention!

(*) By the way, why does Map implement "V get(Object key)" and not "V get(K key)"??

0

There are 0 answers