Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by FilipSAdamsen:
http://wiki.apache.org/tapestry/Tapestry5HowToAddMapBindingPrefix

New page:
This page describes how to add a map binding prefix to Tapestry 5.

The map binding prefix allows you to specify a map like this:
{{{
${map:key1=value1,key2=value2} or <t:component 
t:parameter="map:key1=value1,key2=value2"/>
}}}

This will create a Map<String, Object> with key1 and key2 as keys and the 
values of the bindings value1 and value2 as values.

First create the !MapBinding:
{{{
public class MapBinding extends AbstractBinding {

  private final Map<String, Binding> delegates;
  private final boolean invariant;

  public MapBinding(Map<String, Binding> delegates, boolean invariant) {
    this.delegates = delegates;
    this.invariant = invariant;
  }

  public Object get() {
    Map<String, Object> values = new HashMap<String, Object>(delegates.size());

    for (Map.Entry<String, Binding> entry : delegates.entrySet()) {
      values.put(entry.getKey(), entry.getValue().get());
    }

    return values;
  }

  public boolean isInvariant() {
    return invariant;
  }

  public Class<Map> getBindingType() {
    return Map.class;
  }
}
}}}

Then create the !MapBindingFactory:
{{{
/**
 * Factory for map bindings. Map bindings parse comma-delimited lists of 
key=value pairs into [EMAIL PROTECTED] Map maps}. Keys are
 * always string literals while the values can be any binding expression, for 
which the default prefix is prop.
 */
public class MapBindingFactory implements BindingFactory {

  private final BindingSource bindingSource;

  public MapBindingFactory(BindingSource source) {
    this.bindingSource = source;
  }

  public Binding newBinding(String description, ComponentResources container, 
ComponentResources component,
                            String expression, Location location) {
    Map<String, Binding> delegates = new HashMap<String, Binding>();
    String[] entries = expression.split(",");
    boolean invariant = true;

    for (String entry : entries) {
      String[] parts = entry.split("=");

      if (parts.length != 2) throw new RuntimeException(String.format("Entry 
'%s' is malformed", entry));

      String name = parts[0];
      String value = parts[1];

      Binding binding = bindingSource.newBinding(description, container, 
component,
                                                 BindingConstants.PROP, value, 
location);
      invariant = invariant && binding.isInvariant();
      delegates.put(name, binding);
    }

    return new MapBinding(delegates, invariant);
  }
}
}}}

And then contribute it to the !BindingSource configuration:
{{{
  public static void contributeBindingSource(MappedConfiguration<String, 
BindingFactory> configuration,
                                             BindingSource bindingSource) {
    configuration.add("map", new MapBindingFactory(bindingSource));
  }
}}}

Again, the keys are always string literals and the values themselves can be any 
binding expression, for which the default binding prefix is prop.

That's all there is to it.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to