| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
| TemplateBinding |
|
| 2.2;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 | * <binding name="effects" value="template:some id is ${currNote.id}."/> |
|
| 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 | * <binding name="effects" value="template:%message-code"/> |
|
| 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 | } |