Clover coverage report - brownies library - 1.0-beta-1
Coverage timestamp: 月 8 16 2004 17:14:42 GMT+09:00
file stats: LOC: 541   Methods: 17
NCLOC: 328   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
BaseDesktopComponentTemplateLoader.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  * Joey and its relative products are published under the terms
 3   
  * of the Apache Software License.
 4   
  */
 5   
 package org.asyrinx.brownie.tapestry.components.layer;
 6   
 
 7   
 import java.util.HashSet;
 8   
 import java.util.Iterator;
 9   
 import java.util.Map;
 10   
 import java.util.Set;
 11   
 
 12   
 import org.apache.commons.lang.builder.ToStringBuilder;
 13   
 import org.apache.commons.logging.Log;
 14   
 import org.apache.commons.logging.LogFactory;
 15   
 import org.apache.tapestry.ApplicationRuntimeException;
 16   
 import org.apache.tapestry.IBinding;
 17   
 import org.apache.tapestry.IComponent;
 18   
 import org.apache.tapestry.ILocation;
 19   
 import org.apache.tapestry.IMarkupWriter;
 20   
 import org.apache.tapestry.IRender;
 21   
 import org.apache.tapestry.IRequestCycle;
 22   
 import org.apache.tapestry.Tapestry;
 23   
 import org.apache.tapestry.binding.ExpressionBinding;
 24   
 import org.apache.tapestry.binding.StaticBinding;
 25   
 import org.apache.tapestry.binding.StringBinding;
 26   
 import org.apache.tapestry.engine.IPageLoader;
 27   
 import org.apache.tapestry.engine.IPageSource;
 28   
 import org.apache.tapestry.engine.ITemplateSource;
 29   
 import org.apache.tapestry.parse.AttributeType;
 30   
 import org.apache.tapestry.parse.CloseToken;
 31   
 import org.apache.tapestry.parse.ComponentTemplate;
 32   
 import org.apache.tapestry.parse.LocalizationToken;
 33   
 import org.apache.tapestry.parse.OpenToken;
 34   
 import org.apache.tapestry.parse.TemplateAttribute;
 35   
 import org.apache.tapestry.parse.TemplateToken;
 36   
 import org.apache.tapestry.parse.TextToken;
 37   
 import org.apache.tapestry.parse.TokenType;
 38   
 import org.apache.tapestry.spec.IComponentSpecification;
 39   
 
 40   
 /**
 41   
  **/
 42   
 
 43   
 public class BaseDesktopComponentTemplateLoader {
 44   
     private static final Log LOG = LogFactory
 45   
             .getLog(BaseDesktopComponentTemplateLoader.class);
 46   
 
 47   
     private IPageLoader _pageLoader;
 48   
 
 49   
     private IRequestCycle _requestCycle;
 50   
 
 51   
     private BaseDesktopComponent _loadComponent;
 52   
 
 53   
     private IPageSource _pageSource;
 54   
 
 55   
     private ComponentTemplate _template;
 56   
 
 57   
     private IComponent[] _stack;
 58   
 
 59   
     private int _stackx = 0;
 60   
 
 61   
     private IComponent _activeComponent = null;
 62   
 
 63   
     private Set _seenIds = new HashSet();
 64   
 
 65   
     /**
 66   
      * A class used with invisible localizations. Constructed from a
 67   
      * {@link TextToken}.
 68   
      * 
 69   
      *  
 70   
      */
 71   
 
 72   
     private static class LocalizedStringRender implements IRender {
 73   
         private IComponent _component;
 74   
 
 75   
         private String _key;
 76   
 
 77   
         private Map _attributes;
 78   
 
 79   
         private String _value;
 80   
 
 81   
         private boolean _raw;
 82   
 
 83  0
         private LocalizedStringRender(IComponent component,
 84   
                 LocalizationToken token) {
 85  0
             _component = component;
 86  0
             _key = token.getKey();
 87  0
             _raw = token.isRaw();
 88  0
             _attributes = token.getAttributes();
 89   
         }
 90   
 
 91  0
         public void render(IMarkupWriter writer, IRequestCycle cycle) {
 92  0
             if (cycle.isRewinding())
 93  0
                 return;
 94   
 
 95  0
             if (_attributes != null) {
 96  0
                 writer.begin("span");
 97   
 
 98  0
                 Iterator i = _attributes.entrySet().iterator();
 99   
 
 100  0
                 while (i.hasNext()) {
 101  0
                     Map.Entry entry = (Map.Entry) i.next();
 102  0
                     String attributeName = (String) entry.getKey();
 103  0
                     String attributeValue = (String) entry.getValue();
 104   
 
 105  0
                     writer.attribute(attributeName, attributeValue);
 106   
                 }
 107   
             }
 108   
 
 109  0
             if (_value == null)
 110  0
                 _value = _component.getMessage(_key);
 111   
 
 112  0
             if (_raw)
 113  0
                 writer.printRaw(_value);
 114   
             else
 115  0
                 writer.print(_value);
 116   
 
 117  0
             if (_attributes != null)
 118  0
                 writer.end();
 119   
         }
 120   
 
 121  0
         public String toString() {
 122  0
             ToStringBuilder builder = new ToStringBuilder(this);
 123   
 
 124  0
             builder.append("component", _component);
 125  0
             builder.append("key", _key);
 126  0
             builder.append("raw", _raw);
 127  0
             builder.append("attributes", _attributes);
 128   
 
 129  0
             return builder.toString();
 130   
         }
 131   
 
 132   
     }
 133   
 
 134  0
     public BaseDesktopComponentTemplateLoader(IRequestCycle requestCycle,
 135   
             IPageLoader pageLoader, BaseDesktopComponent loadComponent,
 136   
             ComponentTemplate template, IPageSource pageSource) {
 137  0
         _requestCycle = requestCycle;
 138  0
         _pageLoader = pageLoader;
 139  0
         _loadComponent = loadComponent;
 140  0
         _template = template;
 141  0
         _pageSource = pageSource;
 142   
 
 143  0
         _stack = new IComponent[template.getTokenCount()];
 144   
     }
 145   
 
 146  0
     public void process() {
 147  0
         int count = _template.getTokenCount();
 148   
 
 149  0
         for (int i = 0; i < count; i++) {
 150  0
             TemplateToken token = _template.getToken(i);
 151   
 
 152  0
             TokenType type = token.getType();
 153   
 
 154  0
             if (type == TokenType.TEXT) {
 155  0
                 process((TextToken) token);
 156  0
                 continue;
 157   
             }
 158   
 
 159  0
             if (type == TokenType.OPEN) {
 160  0
                 process((OpenToken) token);
 161  0
                 continue;
 162   
             }
 163   
 
 164  0
             if (type == TokenType.CLOSE) {
 165  0
                 process((CloseToken) token);
 166  0
                 continue;
 167   
             }
 168   
 
 169  0
             if (type == TokenType.LOCALIZATION) {
 170  0
                 process((LocalizationToken) token);
 171  0
                 continue;
 172   
             }
 173   
         }
 174   
 
 175   
         // This is also pretty much unreachable, and the message is kind of out
 176   
         // of date, too.
 177   
 
 178  0
         if (_stackx != 0)
 179  0
             throw new ApplicationRuntimeException(Tapestry
 180   
                     .getMessage("BaseDesktopComponent.unbalance-open-tags"),
 181   
                     _loadComponent, null, null);
 182   
 
 183  0
         checkAllComponentsReferenced();
 184   
     }
 185   
 
 186   
     /**
 187   
      * Adds the token (which implements {@link IRender}) to the active
 188   
      * component (using {@link IComponent#addBody(IRender)}), or to this
 189   
      * component {@link #addOuter(IRender)}.
 190   
      * 
 191   
      * <p>
 192   
      * A check is made that the active component allows a body.
 193   
      *  
 194   
      */
 195   
 
 196  0
     private void process(TextToken token) {
 197  0
         if (_activeComponent == null) {
 198  0
             _loadComponent.addOuter(token);
 199  0
             return;
 200   
         }
 201   
 
 202  0
         if (!_activeComponent.getSpecification().getAllowBody())
 203  0
             throw createBodylessComponentException(_activeComponent);
 204   
 
 205  0
         _activeComponent.addBody(token);
 206   
     }
 207   
 
 208  0
     private void process(OpenToken token) {
 209  0
         String id = token.getId();
 210  0
         IComponent component = null;
 211  0
         String componentType = token.getComponentType();
 212   
 
 213  0
         if (componentType == null)
 214  0
             component = getEmbeddedComponent(id);
 215   
         else
 216  0
             component = createImplicitComponent(id, componentType, token
 217   
                     .getLocation());
 218   
 
 219   
         // Make sure the template contains each component only once.
 220   
 
 221  0
         if (_seenIds.contains(id))
 222  0
             throw new ApplicationRuntimeException(Tapestry.format(
 223   
                     "BaseDesktopComponent.multiple-component-references",
 224   
                     _loadComponent.getExtendedId(), id), _loadComponent, token
 225   
                     .getLocation(), null);
 226   
 
 227  0
         _seenIds.add(id);
 228   
 
 229  0
         if (_activeComponent == null)
 230  0
             _loadComponent.addOuter(component);
 231   
         else {
 232   
             // Note: this code may no longer be reachable (because the
 233   
             // template parser does this check first).
 234   
 
 235  0
             if (!_activeComponent.getSpecification().getAllowBody())
 236  0
                 throw createBodylessComponentException(_activeComponent);
 237   
 
 238  0
             _activeComponent.addBody(component);
 239   
         }
 240   
 
 241  0
         addTemplateBindings(component, token);
 242   
 
 243  0
         _stack[_stackx++] = _activeComponent;
 244   
 
 245  0
         _activeComponent = component;
 246   
     }
 247   
 
 248  0
     private IComponent createImplicitComponent(String id, String componentType,
 249   
             ILocation location) {
 250  0
         IComponent result = _pageLoader.createImplicitComponent(_requestCycle,
 251   
                 _loadComponent, id, componentType, location);
 252   
 
 253  0
         return result;
 254   
     }
 255   
 
 256  0
     private IComponent getEmbeddedComponent(String id) {
 257  0
         return _loadComponent.getComponent(id);
 258   
     }
 259   
 
 260  0
     private void process(CloseToken token) {
 261   
         // Again, this is pretty much impossible to reach because
 262   
         // the template parser does a great job.
 263   
 
 264  0
         if (_stackx <= 0)
 265  0
             throw new ApplicationRuntimeException(Tapestry
 266   
                     .getMessage("BaseDesktopComponent.unbalanced-close-tags"),
 267   
                     _loadComponent, token.getLocation(), null);
 268   
 
 269   
         // Null and forget the top element on the stack.
 270   
 
 271  0
         _stack[_stackx--] = null;
 272   
 
 273  0
         _activeComponent = _stack[_stackx];
 274   
     }
 275   
 
 276  0
     private void process(LocalizationToken token) {
 277  0
         IRender render = new LocalizedStringRender(_loadComponent, token);
 278   
 
 279  0
         if (_activeComponent == null)
 280  0
             _loadComponent.addOuter(render);
 281   
         else
 282  0
             _activeComponent.addBody(render);
 283   
     }
 284   
 
 285   
     /**
 286   
      * Adds bindings based on attributes in the template.
 287   
      * 
 288   
      * @since 3.0
 289   
      *  
 290   
      */
 291   
 
 292  0
     private void addTemplateBindings(IComponent component, OpenToken token) {
 293  0
         IComponentSpecification spec = component.getSpecification();
 294   
 
 295   
         // add a static binding carrying the template tag
 296  0
         addStaticBinding(component, spec,
 297   
                 ITemplateSource.TEMPLATE_TAG_PARAMETER_NAME, token.getTag(),
 298   
                 token.getLocation());
 299   
 
 300  0
         Map attributes = token.getAttributesMap();
 301   
 
 302  0
         if (attributes == null)
 303  0
             return;
 304   
 
 305  0
         Iterator i = attributes.entrySet().iterator();
 306   
 
 307  0
         while (i.hasNext()) {
 308  0
             Map.Entry entry = (Map.Entry) i.next();
 309   
 
 310  0
             String name = (String) entry.getKey();
 311  0
             TemplateAttribute attribute = (TemplateAttribute) entry.getValue();
 312  0
             AttributeType type = attribute.getType();
 313   
 
 314  0
             if (type == AttributeType.OGNL_EXPRESSION) {
 315  0
                 addExpressionBinding(component, spec, name, attribute
 316   
                         .getValue(), token.getLocation());
 317  0
                 continue;
 318   
             }
 319   
 
 320  0
             if (type == AttributeType.LOCALIZATION_KEY) {
 321  0
                 addStringBinding(component, spec, name, attribute.getValue(),
 322   
                         token.getLocation());
 323  0
                 continue;
 324   
             }
 325   
 
 326  0
             if (type == AttributeType.LITERAL)
 327  0
                 addStaticBinding(component, spec, name, attribute.getValue(),
 328   
                         token.getLocation());
 329   
         }
 330   
     }
 331   
 
 332   
     /**
 333   
      * Adds an expression binding, checking for errors related to reserved and
 334   
      * informal parameters.
 335   
      * 
 336   
      * <p>
 337   
      * It is an error to specify expression bindings in both the specification
 338   
      * and the template.
 339   
      * 
 340   
      * @since 3.0
 341   
      */
 342   
 
 343  0
     private void addExpressionBinding(IComponent component,
 344   
             IComponentSpecification spec, String name, String expression,
 345   
             ILocation location) {
 346   
 
 347   
         // If matches a formal parameter name, allow it to be set
 348   
         // unless there's already a binding.
 349   
 
 350  0
         boolean isFormal = (spec.getParameter(name) != null);
 351   
 
 352  0
         if (isFormal) {
 353  0
             if (component.getBinding(name) != null)
 354  0
                 throw new ApplicationRuntimeException(Tapestry.format(
 355   
                         "BaseDesktopComponent.dupe-template-expression", name,
 356   
                         component.getExtendedId(), _loadComponent
 357   
                                 .getExtendedId()), component, location, null);
 358   
         } else {
 359  0
             if (!spec.getAllowInformalParameters())
 360  0
                 throw new ApplicationRuntimeException(
 361   
                         Tapestry
 362   
                                 .format(
 363   
                                         "BaseDesktopComponent.template-expression-for-informal-parameter",
 364   
                                         name, component.getExtendedId(),
 365   
                                         _loadComponent.getExtendedId()),
 366   
                         component, location, null);
 367   
 
 368   
             // If the name is reserved (matches a formal parameter
 369   
             // or reserved name, caselessly), then skip it.
 370   
 
 371  0
             if (spec.isReservedParameterName(name))
 372  0
                 throw new ApplicationRuntimeException(
 373   
                         Tapestry
 374   
                                 .format(
 375   
                                         "BaseDesktopComponent.template-expression-for-reserved-parameter",
 376   
                                         name, component.getExtendedId(),
 377   
                                         _loadComponent.getExtendedId()),
 378   
                         component, location, null);
 379   
         }
 380   
 
 381  0
         IBinding binding = new ExpressionBinding(_pageSource
 382   
                 .getResourceResolver(), _loadComponent, expression, location);
 383   
 
 384  0
         component.setBinding(name, binding);
 385   
     }
 386   
 
 387   
     /**
 388   
      * Adds an expression binding, checking for errors related to reserved and
 389   
      * informal parameters.
 390   
      * 
 391   
      * <p>
 392   
      * It is an error to specify expression bindings in both the specification
 393   
      * and the template.
 394   
      * 
 395   
      * @since 3.0
 396   
      */
 397   
 
 398  0
     private void addStringBinding(IComponent component,
 399   
             IComponentSpecification spec, String name, String localizationKey,
 400   
             ILocation location) {
 401   
         // If matches a formal parameter name, allow it to be set
 402   
         // unless there's already a binding.
 403   
 
 404  0
         boolean isFormal = (spec.getParameter(name) != null);
 405   
 
 406  0
         if (isFormal) {
 407  0
             if (component.getBinding(name) != null)
 408  0
                 throw new ApplicationRuntimeException(Tapestry.format(
 409   
                         "BaseDesktopComponent.dupe-string", name, component
 410   
                                 .getExtendedId(), _loadComponent
 411   
                                 .getExtendedId()), component, location, null);
 412   
         } else {
 413  0
             if (!spec.getAllowInformalParameters())
 414  0
                 throw new ApplicationRuntimeException(
 415   
                         Tapestry
 416   
                                 .format(
 417   
                                         "BaseDesktopComponent.template-expression-for-informal-parameter",
 418   
                                         name, component.getExtendedId(),
 419   
                                         _loadComponent.getExtendedId()),
 420   
                         component, location, null);
 421   
 
 422   
             // If the name is reserved (matches a formal parameter
 423   
             // or reserved name, caselessly), then skip it.
 424   
 
 425  0
             if (spec.isReservedParameterName(name))
 426  0
                 throw new ApplicationRuntimeException(
 427   
                         Tapestry
 428   
                                 .format(
 429   
                                         "BaseDesktopComponent.template-expression-for-reserved-parameter",
 430   
                                         name, component.getExtendedId(),
 431   
                                         _loadComponent.getExtendedId()),
 432   
                         component, location, null);
 433   
         }
 434   
 
 435  0
         IBinding binding = new StringBinding(_loadComponent, localizationKey,
 436   
                 location);
 437   
 
 438  0
         component.setBinding(name, binding);
 439   
     }
 440   
 
 441   
     /**
 442   
      * Adds a static binding, checking for errors related to reserved and
 443   
      * informal parameters.
 444   
      * 
 445   
      * <p>
 446   
      * Static bindings that conflict with bindings in the specification are
 447   
      * quietly ignored.
 448   
      * 
 449   
      * @since 3.0
 450   
      *  
 451   
      */
 452   
 
 453  0
     private void addStaticBinding(IComponent component,
 454   
             IComponentSpecification spec, String name, String staticValue,
 455   
             ILocation location) {
 456   
 
 457  0
         if (component.getBinding(name) != null)
 458  0
             return;
 459   
 
 460   
         // If matches a formal parameter name, allow it to be set
 461   
         // unless there's already a binding.
 462   
 
 463  0
         boolean isFormal = (spec.getParameter(name) != null);
 464   
 
 465  0
         if (!isFormal) {
 466   
             // Skip informal parameters if the component doesn't allow them.
 467   
 
 468  0
             if (!spec.getAllowInformalParameters())
 469  0
                 return;
 470   
 
 471   
             // If the name is reserved (matches a formal parameter
 472   
             // or reserved name, caselessly), then skip it.
 473   
 
 474  0
             if (spec.isReservedParameterName(name))
 475  0
                 return;
 476   
         }
 477   
 
 478  0
         IBinding binding = new StaticBinding(staticValue, location);
 479   
 
 480  0
         component.setBinding(name, binding);
 481   
     }
 482   
 
 483  0
     private void checkAllComponentsReferenced() {
 484   
         // First, contruct a modifiable copy of the ids of all expected
 485   
         // components
 486   
         // (that is, components declared in the specification).
 487   
 
 488  0
         Map components = _loadComponent.getComponents();
 489   
 
 490  0
         Set ids = components.keySet();
 491   
 
 492   
         // If the seen ids ... ids referenced in the template, matches
 493   
         // all the ids in the specification then we're fine.
 494   
 
 495  0
         if (_seenIds.containsAll(ids))
 496  0
             return;
 497   
 
 498   
         // Create a modifiable copy. Remove the ids that are referenced in
 499   
         // the template. The remainder are worthy of note.
 500   
 
 501  0
         ids = new HashSet(ids);
 502  0
         ids.removeAll(_seenIds);
 503   
 
 504  0
         int count = ids.size();
 505   
 
 506  0
         String key = (count == 1) ? "BaseDesktopComponent.missing-component-spec-single"
 507   
                 : "BaseDesktopComponent.missing-component-spec-multi";
 508   
 
 509  0
         StringBuffer buffer = new StringBuffer(Tapestry.format(key,
 510   
                 _loadComponent.getExtendedId()));
 511   
 
 512  0
         Iterator i = ids.iterator();
 513  0
         int j = 1;
 514   
 
 515  0
         while (i.hasNext()) {
 516  0
             if (j == 1)
 517  0
                 buffer.append(' ');
 518  0
             else if (j == count) {
 519  0
                 buffer.append(' ');
 520  0
                 buffer.append(Tapestry.getMessage("BaseDesktopComponent.and"));
 521  0
                 buffer.append(' ');
 522   
             } else
 523  0
                 buffer.append(", ");
 524   
 
 525  0
             buffer.append(i.next());
 526   
 
 527  0
             j++;
 528   
         }
 529   
 
 530  0
         buffer.append('.');
 531   
 
 532  0
         LOG.error(buffer.toString());
 533   
     }
 534   
 
 535  0
     protected ApplicationRuntimeException createBodylessComponentException(
 536   
             IComponent component) {
 537  0
         return new ApplicationRuntimeException(Tapestry
 538   
                 .getMessage("BaseComponentTemplateLoader.bodyless-component"),
 539   
                 component, null, null);
 540   
     }
 541   
 }