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/Tapestry5HowToAddMessageFormatBindingPrefix

The comment on the change is:
Rewrote implementation and added some new features including multi-part keys.

------------------------------------------------------------------------------
  ## page was renamed from Tapestry5HowToAddMessageFormatPrefix
- This page describes how to add a messageformat prefix to Tapestry 5.
+ This page describes how to add a format prefix to Tapestry 5.
  
- The messageformat prefix allows you to specify values to use in a message 
inline like this:
+ The format prefix allows you to specify values to use in a message inline 
like this:
  {{{
- ${messageformat:key=value1,value2} or <t:component 
t:parameter="messageformat:key=value1,value2">
+ ${format:key=value1,value2} or <t:component 
t:parameter="format:key=value1,value2"/>
  }}}
  
  Where the component's message catalog contains:
@@ -13, +13 @@

  key = This is the first value: %s, it's a string. This is the second value: 
%d, it's a number.
  }}}
  
- First create the !MessageFormatBinding:
+ First create the !FormatBinding:
  {{{
- public class MessageFormatBinding extends AbstractBinding {
+ public class FormatBinding extends AbstractBinding {
  
-   private final String messageKey;
    private final Messages messages;
-   private final List<Binding> bindings;
    private final boolean invariant;
+   private final List<Binding> keyBindings;
+   private final List<Binding> valueBindings;
  
-   public MessageFormatBinding(Location location, String messageKey, Messages 
messages, List<Binding> bindings, boolean invariant) {
+   public FormatBinding(Location location, Messages messages, boolean 
invariant,
+                        ArrayList<Binding> keyBindings, List<Binding> 
valueBindings) {
      super(location);
  
-     this.messageKey = messageKey;
      this.messages = messages;
-     this.bindings = bindings;
      this.invariant = invariant;
+     this.keyBindings = keyBindings;
+     this.valueBindings = valueBindings;
+   }
+ 
+   public FormatBinding(Location location, Messages messages, boolean 
invariant, ArrayList<Binding> keyBindings) {
+     super(location);
+ 
+     this.messages = messages;
+     this.invariant = invariant;
+     this.keyBindings = keyBindings;
+     this.valueBindings = null;
    }
  
    public Object get() {
-     List<Object> values = new ArrayList<Object>(bindings.size());
+     String key = "";
-     for (Binding binding : bindings)
+     for (Binding keyBinding : keyBindings) {
-       values.add(binding.get());
+       key += keyBinding.get();
+     }
  
+     if (null == valueBindings) return messages.get(key);
+ 
+     List<Object> values = new ArrayList<Object>(valueBindings.size());
+     for (Binding valueBinding : valueBindings) {
+       values.add(valueBinding.get());
+     }
+ 
-     return messages.format(messageKey, values.toArray());
+     return messages.format(key, values.toArray());
    }
  
-   @Override
    public boolean isInvariant() {
      return this.invariant;
    }
  
-   @Override
+   @SuppressWarnings("unchecked")
    public Class getBindingType() {
      return String.class;
    }
  }
  }}}
  
- Then create the class !MessageFormatBindingFactory:
+ Then create the class !FormatBindingFactory:
  {{{
- public class MessageFormatBindingFactory implements BindingFactory {
+ public class FormatBindingFactory
+     implements BindingFactory {
+ 
+   private static final String SEPARATOR = "=";
+   private static final String DELIMITER = ",";
+ 
+   private static final String KEY_PREFIX = 
TapestryConstants.LITERAL_BINDING_PREFIX;
+   private static final String VALUE_PREFIX = 
TapestryConstants.PROP_BINDING_PREFIX;
  
    private final BindingSource bindingSource;
  
-   public MessageFormatBindingFactory(BindingSource bindingSource) {
+   public FormatBindingFactory(BindingSource bindingSource) {
      this.bindingSource = bindingSource;
    }
  
    public Binding newBinding(String description, ComponentResources container, 
ComponentResources component,
                              String expression, Location location) {
+     int separatorIndex = expression.indexOf(SEPARATOR);
-     String messageKey = expression.substring(0, expression.indexOf('='));
-     List<String> parts = 
Arrays.asList(expression.substring(expression.indexOf('=') + 1).split(","));
  
+     if (-1 == separatorIndex) {
+       List<String> keys = Arrays.asList(expression.split(DELIMITER));
-     ArrayList<Binding> bindings = new ArrayList<Binding>(parts.size());
-     for (String part : parts) {
-       String prefix = TapestryConstants.PROP_BINDING_PREFIX;
  
+       ArrayList<Binding> keyBindings = createBindings(description, container, 
component, KEY_PREFIX, keys, location);
-       if ('\'' == part.charAt(0) && '\'' == part.charAt(part.length() - 1)) {
-         part = part.substring(1, part.length() - 1);
-         prefix = TapestryConstants.LITERAL_BINDING_PREFIX;
-       }
  
-       bindings.add(bindingSource.newBinding(description, container, 
component, prefix, part, location));
+       boolean invariant = isInvariant(keyBindings);
+       return new FormatBinding(location, container.getMessages(), invariant, 
keyBindings);
      }
  
-     boolean invariant = true;
-     for (Binding binding : bindings) {
-       if (false == binding.isInvariant()) {
-         invariant = false;
-         break;
-       }
+     List<String> keys = Arrays.asList(expression.substring(0, 
separatorIndex).split(DELIMITER));
+     ArrayList<Binding> keyBindings = createBindings(description, container, 
component, KEY_PREFIX, keys, location);
+ 
+     List<String> values = Arrays.asList(expression.substring(separatorIndex + 
1).split(DELIMITER));
+     ArrayList<Binding> valueBindings = createBindings(description, container, 
component, VALUE_PREFIX, values,
+                                                       location);
+ 
+     boolean invariant = isInvariant(keyBindings) && 
isInvariant(valueBindings);
+     return new FormatBinding(location, container.getMessages(), invariant, 
keyBindings, valueBindings);
+   }
+ 
+   private ArrayList<Binding> createBindings(String description, 
ComponentResources container,
+                                             ComponentResources component, 
String defaultPrefix,
+                                             List<String> expressions, 
Location location) {
+     ArrayList<Binding> bindings = new ArrayList<Binding>(expressions.size());
+ 
+     for (String expression : expressions) {
+       bindings.add(bindingSource.newBinding(description, container, 
component, defaultPrefix, expression, location));
      }
  
-     return new MessageFormatBinding(location, messageKey, 
component.getMessages(), bindings, invariant);
+     return bindings;
+   }
+ 
+   private boolean isInvariant(ArrayList<Binding> bindings) {
+     for (Binding binding : bindings) {
+       if (!binding.isInvariant()) return false;
+     }
+ 
+     return true;
    }
  }
  }}}
@@ -95, +135 @@

  {{{
    public static void contributeBindingSource(MappedConfiguration<String, 
BindingFactory> configuration,
                                               BindingSource bindingSource) {
-     configuration.add("messageformat", new 
MessageFormatBindingFactory(bindingSource));
+     configuration.add("format", new FormatBindingFactory(bindingSource));
    }
  }}}
  
- A few things to note about the use of this prefix:
+ Notes about the key part of the binding:
+ 
+  1. The key can contain multiple parts separated by commas, and
+  2. each part of the key can use an optional binding prefix (defaults to 
literal).
+ 
+ This means you can do stuff like ${format:gender-,prop:user.gender} which 
will look up the messages gender-male and gender-female depending on the value 
of user.gender.
+ 
+ Notes about the value part of the binding:
  
   1. Literal values should be enclosed in single quotes, and
   2. it is possible to use other prefixes for the values.

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

Reply via email to