Coverage Report - net.sf.tacos.binding.TemplateBinding
 
Classes in this File Line Coverage Branch Coverage Complexity
TemplateBinding
0% 
0% 
2,2
 
 1  
 /*
 2  
  * TemplateBinding.java
 3  
  */ 
 4  
 
 5  
 package net.sf.tacos.binding;
 6  
 
 7  
 import org.apache.commons.lang.StringUtils;
 8  
 import org.apache.hivemind.Location;
 9  
 import org.apache.tapestry.IBinding;
 10  
 import org.apache.tapestry.IComponent;
 11  
 import org.apache.tapestry.binding.AbstractBinding;
 12  
 import org.apache.tapestry.binding.BindingFactory;
 13  
 import org.apache.tapestry.coerce.ValueConverter;
 14  
 
 15  
 import java.util.HashMap;
 16  
 import java.util.Iterator;
 17  
 import java.util.Map;
 18  
 
 19  
 /**
 20  
  * An implementation of Tapestry {@link IBinding} that provides a binding
 21  
  * similar to {@link org.apache.tapestry.binding.LiteralBinding} with the 
 22  
  * additional benefit that it can also include variables.
 23  
  *
 24  
  * The variables should be put into <code>${}</code> .<br/>
 25  
  *
 26  
  * Here's an example:
 27  
  * <code>
 28  
  * &lt;binding name="effects" value="template:some id is ${currNote.id}."/&gt;
 29  
  * </code>
 30  
  * <p/>
 31  
  * <p/>
 32  
  * The binding can also get its content from resource bundles. It will still
 33  
  * go on and process it - looking for variables to substitute.<br/>
 34  
  * Example:
 35  
  * <code>
 36  
  * &lt;binding name="effects" value="template:%message-code"/&gt;
 37  
  * </code>
 38  
  *
 39  
  */
 40  
 public class TemplateBinding extends AbstractBinding
 41  
 {
 42  
     /**
 43  
      * The root object against which the nested property name is evaluated.
 44  
      */
 45  
     private final IComponent root;
 46  
     /**
 47  
      * The expression that have variables, as a string.
 48  
      */
 49  
     private String expression;
 50  
     /**
 51  
      * cache the variable expression and it's compiled binding.
 52  
      */
 53  
     private Map variableBindings;
 54  
     /**
 55  
      * the BindingFactory for creating the inside variable IBinding.
 56  
      */
 57  
     private BindingFactory nestedBindingFactory;
 58  
 
 59  
     /**
 60  
      * constructor
 61  
      *
 62  
      * @param description
 63  
      * @param location
 64  
      * @param valueConverter
 65  
      * @param root                 The root object against which the nested property name is evaluated.
 66  
      * @param expression           plain string or message code in page's specification file.
 67  
      * @param nestedBindingFactory Internal used BindingFactory
 68  
      */
 69  
     public TemplateBinding(String description, Location location, ValueConverter valueConverter,
 70  
                            IComponent root, String expression, BindingFactory nestedBindingFactory)
 71  
     {
 72  0
         super(description, valueConverter, location);
 73  0
         this.root = root;
 74  0
         this.expression = extractExpression(expression);
 75  0
         this.nestedBindingFactory = nestedBindingFactory;
 76  0
         buildingVariableBindings();
 77  0
     }
 78  
 
 79  
     /**
 80  
      * build variable binding map.
 81  
      */
 82  
     private void buildingVariableBindings()
 83  
     {
 84  0
         if (variableBindings == null) {
 85  0
             variableBindings = new HashMap();
 86  
         }
 87  0
         String least = expression;
 88  
         int start;
 89  0
         while ((start = least.indexOf("${")) != -1) {
 90  0
             least = least.substring(start);
 91  0
             int length = least.indexOf("}");
 92  0
             String innerExp = least.substring(2, length);
 93  0
             IBinding expBinding = nestedBindingFactory.createBinding(root, getDescription(), innerExp, getLocation());
 94  0
             variableBindings.put("${" + innerExp + "}", expBinding);
 95  0
             least = least.substring(length + 1);
 96  0
         }
 97  0
     }
 98  
 
 99  
     /**
 100  
      * Extract expression if it is indicated as message code.
 101  
      *
 102  
      * @param expr
 103  
      * @return real evaluated expression.
 104  
      */
 105  
     private String extractExpression(String expr)
 106  
     {
 107  0
         if (expr.startsWith("%")) {
 108  0
             String key = expr.substring(1);
 109  0
             return root.getMessages().getMessage(key);
 110  
         }
 111  0
         return expr;
 112  
     }
 113  
 
 114  
     /**
 115  
      * Evaluate the value with inside variables.
 116  
      *
 117  
      * @return binding value
 118  
      */
 119  
     public Object getObject()
 120  
     {
 121  0
         String value = expression;
 122  0
         Iterator it = variableBindings.entrySet().iterator();
 123  0
         while (it.hasNext()) {
 124  0
             Map.Entry entry = (Map.Entry) it.next();
 125  0
             String key = (String) entry.getKey();
 126  0
             IBinding exp = (IBinding) entry.getValue();
 127  0
             String replacement = "";
 128  0
             Object object = exp.getObject();
 129  0
             if (object != null) {
 130  0
                 replacement = object.toString();
 131  
             }
 132  0
             value = StringUtils.replace(value, key, replacement);
 133  0
         }
 134  0
         return value;
 135  
     }
 136  
 
 137  
     /**
 138  
      * Should be variant because of inside ognl expression.
 139  
      *
 140  
      * @return indicate it is variant.
 141  
      * @see org.apache.tapestry.IBinding#isInvariant()
 142  
      */
 143  
     public boolean isInvariant()
 144  
     {
 145  0
         return false;
 146  
     }
 147  
 }