Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/tapestry/AbstractComponent.java


1   /* $$ Clover has instrumented this file $$ */// Copyright 2004 The Apache Software Foundation
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package org.apache.tapestry;
16  
17  import java.util.Collection;
18  import java.util.Collections;
19  import java.util.HashMap;
20  import java.util.HashSet;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import ognl.OgnlRuntime;
26  
27  import org.apache.hivemind.ApplicationRuntimeException;
28  import org.apache.hivemind.ClassResolver;
29  import org.apache.hivemind.Messages;
30  import org.apache.hivemind.impl.BaseLocatable;
31  import org.apache.hivemind.util.PropertyAdaptor;
32  import org.apache.hivemind.util.PropertyUtils;
33  import org.apache.tapestry.bean.BeanProvider;
34  import org.apache.tapestry.bean.BeanProviderPropertyAccessor;
35  import org.apache.tapestry.engine.IPageLoader;
36  import org.apache.tapestry.event.ChangeObserver;
37  import org.apache.tapestry.event.PageDetachListener;
38  import org.apache.tapestry.event.PageEvent;
39  import org.apache.tapestry.event.PageRenderListener;
40  import org.apache.tapestry.event.PageValidateListener;
41  import org.apache.tapestry.listener.ListenerMap;
42  import org.apache.tapestry.param.ParameterManager;
43  import org.apache.tapestry.spec.IComponentSpecification;
44  import org.apache.tapestry.util.prop.OgnlUtils;
45  
46  /**
47   * Abstract base class implementing the {@link IComponent}interface.
48   * 
49   * @author Howard Lewis Ship
50   */
51  
52  public abstract class AbstractComponent extends BaseLocatable implements IComponent
53  {public static com.cortexeb.tools.clover.d __CLOVER_0_0 = com.cortexeb.tools.clover.aq.getRecorder(new char[] {67,58,92,119,111,114,107,115,112,97,99,101,92,106,97,107,97,114,116,97,45,116,97,112,101,115,116,114,121,92,102,114,97,109,101,119,111,114,107,92,116,97,114,103,101,116,92,99,108,111,118,101,114,45,100,98},1097019445706L);
54      /**
55       * Used to check that subclasses invoke this implementation of prepareForRender().
56       * 
57       * @see Tapestry#checkMethodInvocation(Object, String, Object)
58       * @since 3.0
59       */
60      private final static String PREPAREFORRENDER_METHOD_ID = "AbstractComponent.prepareForRender()";
61  
62      /**
63       * Used to check that subclasses invoke this implementation of cleanupAfterRender().
64       * 
65       * @see Tapestry#checkMethodInvocation(Object, String, Object)
66       * @since 3.0
67       */
68  
69      private final static String CLEANUPAFTERRENDER_METHOD_ID = "AbstractComponent.cleanupAfterRender()";
70  
71      static
72      {
73          // Register the BeanProviderHelper to provide access to the
74          // beans of a bean provider as named properties.
75  
76          __CLOVER_0_0.S[10690]++;OgnlRuntime.setPropertyAccessor(IBeanProvider.class, new BeanProviderPropertyAccessor());
77      }
78  
79      /**
80       * The specification used to originally build the component.
81       */
82  
83      private IComponentSpecification _specification;
84  
85      /**
86       * The page that contains the component, possibly itself (if the component is in fact, a page).
87       */
88  
89      private IPage _page;
90  
91      /**
92       * The component which contains the component. This will only be null if the component is
93       * actually a page.
94       */
95  
96      private IComponent _container;
97  
98      /**
99       * The simple id of this component.
100      */
101 
102     private String _id;
103 
104     /**
105      * The fully qualified id of this component. This is calculated the first time it is needed,
106      * then cached for later.
107      */
108 
109     private String _idPath;
110 
111     private static final int MAP_SIZE = 5;
112 
113     /**
114      * A {@link Map}of all bindings (for which there isn't a corresponding JavaBeans property); the
115      * keys are the names of formal and informal parameters.
116      */
117 
118     private Map _bindings;
119 
120     private Map _components;
121 
122     private static final int BODY_INIT_SIZE = 5;
123 
124     private INamespace _namespace;
125 
126     /**
127      * Used in place of JDK 1.3's Collections.EMPTY_MAP (which is not available in JDK 1.2).
128      */
129 
130     private static final Map EMPTY_MAP = Collections.unmodifiableMap(new HashMap(1));
131 
132     /**
133      * The number of {@link IRender}objects in the body of this component.
134      */
135 
136     private int _bodyCount = 0;
137 
138     /**
139      * An aray of elements in the body of this component.
140      */
141 
142     private IRender[] _body;
143 
144     /**
145      * The components' asset map.
146      */
147 
148     private Map _assets;
149 
150     /**
151      * A mapping that allows public instance methods to be dressed up as {@link IActionListener}
152      * listener objects.
153      * 
154      * @since 1.0.2
155      */
156 
157     private ListenerMap _listeners;
158 
159     /**
160      * A bean provider; these are lazily created as needed.
161      * 
162      * @since 1.0.4
163      */
164 
165     private IBeanProvider _beans;
166 
167     /**
168      * Manages setting and clearing parameter properties for the component.
169      * 
170      * @since 2.0.3
171      */
172 
173     private ParameterManager _parameterManager;
174 
175     /**
176      * Provides access to localized Strings for this component.
177      * 
178      * @since 2.0.4
179      */
180 
181     private Messages _strings;
182 
183     public void addAsset(String name, IAsset asset)
184     {try { __CLOVER_0_0.M[2650]++;
185         __CLOVER_0_0.S[10691]++;if ((((_assets == null) && (++__CLOVER_0_0.CT[1838] != 0)) || (++__CLOVER_0_0.CF[1838] == 0))){
186             __CLOVER_0_0.S[10692]++;_assets = new HashMap(MAP_SIZE);}
187 
188         __CLOVER_0_0.S[10693]++;_assets.put(name, asset);
189     } finally { }}
190 
191     public void addComponent(IComponent component)
192     {try { __CLOVER_0_0.M[2651]++;
193         __CLOVER_0_0.S[10694]++;if ((((_components == null) && (++__CLOVER_0_0.CT[1839] != 0)) || (++__CLOVER_0_0.CF[1839] == 0))){
194             __CLOVER_0_0.S[10695]++;_components = new HashMap(MAP_SIZE);}
195 
196         __CLOVER_0_0.S[10696]++;_components.put(component.getId(), component);
197     } finally { }}
198 
199     /**
200      * Adds an element (which may be static text or a component) as a body element of this
201      * component. Such elements are rendered by {@link #renderBody(IMarkupWriter, IRequestCycle)}.
202      * 
203      * @since 2.2
204      */
205 
206     public void addBody(IRender element)
207     {try { __CLOVER_0_0.M[2652]++;
208         // Should check the specification to see if this component
209         // allows body. Curently, this is checked by the component
210         // in render(), which is silly.
211 
212         __CLOVER_0_0.S[10697]++;if ((((_body == null) && (++__CLOVER_0_0.CT[1840] != 0)) || (++__CLOVER_0_0.CF[1840] == 0))){
213         {
214             __CLOVER_0_0.S[10698]++;_body = new IRender[BODY_INIT_SIZE];
215             __CLOVER_0_0.S[10699]++;_body[0] = element;
216 
217             __CLOVER_0_0.S[10700]++;_bodyCount = 1;
218             __CLOVER_0_0.S[10701]++;return;
219         }}
220 
221         // No more room? Make the array bigger.
222 
223         __CLOVER_0_0.S[10702]++;if ((((_bodyCount == _body.length) && (++__CLOVER_0_0.CT[1841] != 0)) || (++__CLOVER_0_0.CF[1841] == 0))){
224         {
225             __CLOVER_0_0.S[10703]++;IRender[] newWrapped;
226 
227             __CLOVER_0_0.S[10704]++;newWrapped = new IRender[_body.length * 2];
228 
229             __CLOVER_0_0.S[10705]++;System.arraycopy(_body, 0, newWrapped, 0, _bodyCount);
230 
231             __CLOVER_0_0.S[10706]++;_body = newWrapped;
232         }}
233 
234         __CLOVER_0_0.S[10707]++;_body[_bodyCount++] = element;
235     } finally { }}
236 
237     /**
238      * Registers this component as a listener of the page if it implements
239      * {@link org.apache.tapestry.event.PageDetachListener}or
240      * {@link org.apache.tapestry.event.PageRenderListener}.
241      * <p>
242      * Invokes {@link #finishLoad()}. Subclasses may overide as needed, but must invoke this
243      * implementation. {@link BaseComponent}loads its HTML template.
244      */
245 
246     public void finishLoad(IRequestCycle cycle, IPageLoader loader,
247             IComponentSpecification specification)
248     {try { __CLOVER_0_0.M[2653]++;
249         __CLOVER_0_0.S[10708]++;if ((((this instanceof PageDetachListener) && (++__CLOVER_0_0.CT[1842] != 0)) || (++__CLOVER_0_0.CF[1842] == 0))){
250             __CLOVER_0_0.S[10709]++;_page.addPageDetachListener((PageDetachListener) this);}
251 
252         __CLOVER_0_0.S[10710]++;if ((((this instanceof PageRenderListener) && (++__CLOVER_0_0.CT[1843] != 0)) || (++__CLOVER_0_0.CF[1843] == 0))){
253             __CLOVER_0_0.S[10711]++;_page.addPageRenderListener((PageRenderListener) this);}
254 
255         __CLOVER_0_0.S[10712]++;if ((((this instanceof PageValidateListener) && (++__CLOVER_0_0.CT[1844] != 0)) || (++__CLOVER_0_0.CF[1844] == 0))){
256             __CLOVER_0_0.S[10713]++;_page.addPageValidateListener((PageValidateListener) this);}
257 
258         __CLOVER_0_0.S[10714]++;finishLoad();
259     } finally { }}
260 
261     /**
262      * Converts informal parameters into additional attributes on the curently open tag.
263      * <p>
264      * Invoked from subclasses to allow additional attributes to be specified within a tag (this
265      * works best when there is a one-to-one corespondence between an {@link IComponent}and a HTML
266      * element.
267      * <p>
268      * Iterates through the bindings for this component. Filters out bindings when the name matches
269      * a formal parameter (as of 1.0.5, informal bindings are weeded out at page load / template
270      * load time, if they match a formal parameter, or a specificied reserved name). For the most
271      * part, all the bindings here are either informal parameter, or formal parameter without a
272      * corresponding JavaBeans property.
273      * <p>
274      * For each acceptible key, the value is extracted using {@link IBinding#getObject()}. If the
275      * value is null, no attribute is written.
276      * <p>
277      * If the value is an instance of {@link IAsset}, then {@link IAsset#buildURL(IRequestCycle)}
278      * is invoked to convert the asset to a URL.
279      * <p>
280      * Finally, {@link IMarkupWriter#attribute(String,String)}is invoked with the value (or the
281      * URL).
282      * <p>
283      * The most common use for informal parameters is to support the HTML class attribute (for use
284      * with cascading style sheets) and to specify JavaScript event handlers.
285      * <p>
286      * Components are only required to generate attributes on the result phase; this can be skipped
287      * during the rewind phase.
288      */
289 
290     protected void renderInformalParameters(IMarkupWriter writer, IRequestCycle cycle)
291     {try { __CLOVER_0_0.M[2654]++;
292         __CLOVER_0_0.S[10715]++;String attribute;
293 
294         __CLOVER_0_0.S[10716]++;if ((((_bindings == null) && (++__CLOVER_0_0.CT[1845] != 0)) || (++__CLOVER_0_0.CF[1845] == 0))){
295             __CLOVER_0_0.S[10717]++;return;}
296 
297         __CLOVER_0_0.S[10718]++;Iterator i = _bindings.entrySet().iterator();
298 
299         __CLOVER_0_0.S[10719]++;while ((((i.hasNext()) && (++__CLOVER_0_0.CT[1846] != 0)) || (++__CLOVER_0_0.CF[1846] == 0))){
300         {
301             __CLOVER_0_0.S[10720]++;Map.Entry entry = (Map.Entry) i.next();
302             __CLOVER_0_0.S[10721]++;String name = (String) entry.getKey();
303 
304             __CLOVER_0_0.S[10722]++;IBinding binding = (IBinding) entry.getValue();
305 
306             __CLOVER_0_0.S[10723]++;Object value = binding.getObject();
307             __CLOVER_0_0.S[10724]++;if ((((value == null) && (++__CLOVER_0_0.CT[1847] != 0)) || (++__CLOVER_0_0.CF[1847] == 0))){
308                 __CLOVER_0_0.S[10725]++;continue;}
309 
310             __CLOVER_0_0.S[10726]++;if ((((value instanceof IAsset) && (++__CLOVER_0_0.CT[1848] != 0)) || (++__CLOVER_0_0.CF[1848] == 0))){
311             {
312                 __CLOVER_0_0.S[10727]++;IAsset asset = (IAsset) value;
313 
314                 // Get the URL of the asset and insert that.
315 
316                 __CLOVER_0_0.S[10728]++;attribute = asset.buildURL(cycle);
317             }}
318             else{
319                 __CLOVER_0_0.S[10729]++;attribute = value.toString();}
320 
321             __CLOVER_0_0.S[10730]++;writer.attribute(name, attribute);
322         }}
323 
324     } finally { }}
325 
326     /**
327      * Returns an object used to resolve classes.
328      * 
329      * @since 3.0
330      */
331     private ClassResolver getClassResolver()
332     {try { __CLOVER_0_0.M[2655]++;
333         __CLOVER_0_0.S[10731]++;return getPage().getEngine().getClassResolver();
334     } finally { }}
335 
336     /**
337      * Returns the named binding, or null if it doesn't exist.
338      * <p>
339      * This method looks for a JavaBeans property with an appropriate name, of type {@link IBinding}.
340      * The property should be named <code><i>name</i>Binding</code>. If it exists and is both
341      * readable and writable, then it is accessor method is invoked. Components which implement such
342      * methods can access their own binding through their instance variables instead of invoking
343      * this method, a performance optimization.
344      * 
345      * @see #setBinding(String,IBinding)
346      */
347 
348     public IBinding getBinding(String name)
349     {try { __CLOVER_0_0.M[2656]++;
350         __CLOVER_0_0.S[10732]++;String bindingPropertyName = name + Tapestry.PARAMETER_PROPERTY_NAME_SUFFIX;
351 
352         __CLOVER_0_0.S[10733]++;if ((((PropertyUtils.isReadable(this, bindingPropertyName)
353                 && PropertyUtils.getPropertyType(this, bindingPropertyName).equals(IBinding.class)) && (++__CLOVER_0_0.CT[1849] != 0)) || (++__CLOVER_0_0.CF[1849] == 0))){
354         {
355             __CLOVER_0_0.S[10734]++;return (IBinding) PropertyUtils.read(this, bindingPropertyName);
356         }}
357 
358         __CLOVER_0_0.S[10735]++;if ((((_bindings == null) && (++__CLOVER_0_0.CT[1850] != 0)) || (++__CLOVER_0_0.CF[1850] == 0))){
359             __CLOVER_0_0.S[10736]++;return null;}
360 
361         __CLOVER_0_0.S[10737]++;return (IBinding) _bindings.get(name);
362     } finally { }}
363 
364     /**
365      * Return's the page's change observer. In practical terms, this will be an
366      * {@link org.apache.tapestry.engine.IPageRecorder}.
367      * 
368      * @see IPage#getChangeObserver()
369      * @deprecated To be removed in 3.1; use {@link IPage#getChangeObserver()}.
370      */
371 
372     public ChangeObserver getChangeObserver()
373     {try { __CLOVER_0_0.M[2657]++;
374         __CLOVER_0_0.S[10738]++;return _page.getChangeObserver();
375     } finally { }}
376 
377     public IComponent getComponent(String id)
378     {try { __CLOVER_0_0.M[2658]++;
379         __CLOVER_0_0.S[10739]++;IComponent result = null;
380 
381         __CLOVER_0_0.S[10740]++;if ((((_components != null) && (++__CLOVER_0_0.CT[1851] != 0)) || (++__CLOVER_0_0.CF[1851] == 0))){
382             __CLOVER_0_0.S[10741]++;result = (IComponent) _components.get(id);}
383 
384         __CLOVER_0_0.S[10742]++;if ((((result == null) && (++__CLOVER_0_0.CT[1852] != 0)) || (++__CLOVER_0_0.CF[1852] == 0))){
385             __CLOVER_0_0.S[10743]++;throw new ApplicationRuntimeException(Tapestry.format("no-such-component", this, id),
386                     this, null, null);}
387 
388         __CLOVER_0_0.S[10744]++;return result;
389     } finally { }}
390 
391     public IComponent getContainer()
392     {try { __CLOVER_0_0.M[2659]++;
393         __CLOVER_0_0.S[10745]++;return _container;
394     } finally { }}
395 
396     public void setContainer(IComponent value)
397     {try { __CLOVER_0_0.M[2660]++;
398         __CLOVER_0_0.S[10746]++;if ((((_container != null) && (++__CLOVER_0_0.CT[1853] != 0)) || (++__CLOVER_0_0.CF[1853] == 0))){
399             __CLOVER_0_0.S[10747]++;throw new ApplicationRuntimeException(Tapestry
400                     .getMessage("AbstractComponent.attempt-to-change-container"));}
401 
402         __CLOVER_0_0.S[10748]++;_container = value;
403     } finally { }}
404 
405     /**
406      * Returns the name of the page, a slash, and this component's id path. Pages are different,
407      * they simply return their name.
408      * 
409      * @see #getIdPath()
410      */
411 
412     public String getExtendedId()
413     {try { __CLOVER_0_0.M[2661]++;
414         __CLOVER_0_0.S[10749]++;if ((((_page == null) && (++__CLOVER_0_0.CT[1854] != 0)) || (++__CLOVER_0_0.CF[1854] == 0))){
415             __CLOVER_0_0.S[10750]++;return null;}
416 
417         __CLOVER_0_0.S[10751]++;return _page.getPageName() + "/" + getIdPath();
418     } finally { }}
419 
420     public String getId()
421     {try { __CLOVER_0_0.M[2662]++;
422         __CLOVER_0_0.S[10752]++;return _id;
423     } finally { }}
424 
425     public void setId(String value)
426     {try { __CLOVER_0_0.M[2663]++;
427         __CLOVER_0_0.S[10753]++;if ((((_id != null) && (++__CLOVER_0_0.CT[1855] != 0)) || (++__CLOVER_0_0.CF[1855] == 0))){
428             __CLOVER_0_0.S[10754]++;throw new ApplicationRuntimeException(Tapestry
429                     .getMessage("AbstractComponent.attempt-to-change-component-id"));}
430 
431         __CLOVER_0_0.S[10755]++;_id = value;
432     } finally { }}
433 
434     public String getIdPath()
435     {try { __CLOVER_0_0.M[2664]++;
436         __CLOVER_0_0.S[10756]++;String containerIdPath;
437 
438         __CLOVER_0_0.S[10757]++;if ((((_container == null) && (++__CLOVER_0_0.CT[1856] != 0)) || (++__CLOVER_0_0.CF[1856] == 0))){
439             __CLOVER_0_0.S[10758]++;throw new NullPointerException(Tapestry
440                     .format("AbstractComponent.null-container", this));}
441 
442         __CLOVER_0_0.S[10759]++;containerIdPath = _container.getIdPath();
443 
444         __CLOVER_0_0.S[10760]++;if ((((containerIdPath == null) && (++__CLOVER_0_0.CT[1857] != 0)) || (++__CLOVER_0_0.CF[1857] == 0))){
445             __CLOVER_0_0.S[10761]++;_idPath = _id;}
446         else{
447             __CLOVER_0_0.S[10762]++;_idPath = containerIdPath + "." + _id;}
448 
449         __CLOVER_0_0.S[10763]++;return _idPath;
450     } finally { }}
451 
452     public IPage getPage()
453     {try { __CLOVER_0_0.M[2665]++;
454         __CLOVER_0_0.S[10764]++;return _page;
455     } finally { }}
456 
457     public void setPage(IPage value)
458     {try { __CLOVER_0_0.M[2666]++;
459         __CLOVER_0_0.S[10765]++;if ((((_page != null) && (++__CLOVER_0_0.CT[1858] != 0)) || (++__CLOVER_0_0.CF[1858] == 0))){
460             __CLOVER_0_0.S[10766]++;throw new ApplicationRuntimeException(Tapestry
461                     .getMessage("AbstractComponent.attempt-to-change-page"));}
462 
463         __CLOVER_0_0.S[10767]++;_page = value;
464     } finally { }}
465 
466     public IComponentSpecification getSpecification()
467     {try { __CLOVER_0_0.M[2667]++;
468         __CLOVER_0_0.S[10768]++;return _specification;
469     } finally { }}
470 
471     public void setSpecification(IComponentSpecification value)
472     {try { __CLOVER_0_0.M[2668]++;
473         __CLOVER_0_0.S[10769]++;if ((((_specification != null) && (++__CLOVER_0_0.CT[1859] != 0)) || (++__CLOVER_0_0.CF[1859] == 0))){
474             __CLOVER_0_0.S[10770]++;throw new ApplicationRuntimeException(Tapestry
475                     .getMessage("AbstractComponent.attempt-to-change-spec"));}
476 
477         __CLOVER_0_0.S[10771]++;_specification = value;
478     } finally { }}
479 
480     /**
481      * Renders all elements wrapped by the receiver.
482      */
483 
484     public void renderBody(IMarkupWriter writer, IRequestCycle cycle)
485     {try { __CLOVER_0_0.M[2669]++;
486         __CLOVER_0_0.S[10772]++;for (int i = 0; (((i < _bodyCount) && (++__CLOVER_0_0.CT[1860] != 0)) || (++__CLOVER_0_0.CF[1860] == 0)); i++){
487             __CLOVER_0_0.S[10773]++;_body[i].render(writer, cycle);}
488     } finally { }}
489 
490     /**
491      * Adds the binding with the given name, replacing any existing binding with that name.
492      * <p>
493      * This method checks to see if a matching JavaBeans property (with a name of
494      * <code><i>name</i>Binding</code> and a type of {@link IBinding}) exists. If so, that
495      * property is updated. An optimized component can simply implement accessor and mutator methods
496      * and then access its bindings via its own instance variables, rather than going through {@link
497      * #getBinding(String)}.
498      * <p>
499      * Informal parameters should <em>not</em> be stored in instance variables if {@link
500      * #renderInformalParameters(IMarkupWriter, IRequestCycle)} is to be used. It relies on using
501      * the collection of bindings (to store informal parameters).
502      */
503 
504     public void setBinding(String name, IBinding binding)
505     {try { __CLOVER_0_0.M[2670]++;
506         __CLOVER_0_0.S[10774]++;String bindingPropertyName = name + Tapestry.PARAMETER_PROPERTY_NAME_SUFFIX;
507 
508         __CLOVER_0_0.S[10775]++;if ((((PropertyUtils.isWritable(this, bindingPropertyName)
509                 && PropertyUtils.getPropertyType(this, bindingPropertyName).equals(IBinding.class)) && (++__CLOVER_0_0.CT[1861] != 0)) || (++__CLOVER_0_0.CF[1861] == 0))){
510         {
511             __CLOVER_0_0.S[10776]++;PropertyUtils.write(this, bindingPropertyName, binding);
512             __CLOVER_0_0.S[10777]++;return;
513         }}
514 
515         __CLOVER_0_0.S[10778]++;if ((((_bindings == null) && (++__CLOVER_0_0.CT[1862] != 0)) || (++__CLOVER_0_0.CF[1862] == 0))){
516             __CLOVER_0_0.S[10779]++;_bindings = new HashMap(MAP_SIZE);}
517 
518         __CLOVER_0_0.S[10780]++;_bindings.put(name, binding);
519     } finally { }}
520 
521     public String toString()
522     {try { __CLOVER_0_0.M[2671]++;
523         __CLOVER_0_0.S[10781]++;StringBuffer buffer;
524 
525         __CLOVER_0_0.S[10782]++;buffer = new StringBuffer(super.toString());
526 
527         __CLOVER_0_0.S[10783]++;buffer.append('[');
528 
529         __CLOVER_0_0.S[10784]++;buffer.append(getExtendedId());
530 
531         __CLOVER_0_0.S[10785]++;buffer.append(']');
532 
533         __CLOVER_0_0.S[10786]++;return buffer.toString();
534     } finally { }}
535 
536     /**
537      * Returns an unmodifiable {@link Map}of components, keyed on component id. Never returns null,
538      * but may return an empty map. The returned map is immutable.
539      */
540 
541     public Map getComponents()
542     {try { __CLOVER_0_0.M[2672]++;
543         __CLOVER_0_0.S[10787]++;if ((((_components == null) && (++__CLOVER_0_0.CT[1863] != 0)) || (++__CLOVER_0_0.CF[1863] == 0))){
544             __CLOVER_0_0.S[10788]++;return EMPTY_MAP;}
545 
546         __CLOVER_0_0.S[10789]++;return Collections.unmodifiableMap(_components);
547 
548     } finally { }}
549 
550     public Map getAssets()
551     {try { __CLOVER_0_0.M[2673]++;
552         __CLOVER_0_0.S[10790]++;if ((((_assets == null) && (++__CLOVER_0_0.CT[1864] != 0)) || (++__CLOVER_0_0.CF[1864] == 0))){
553             __CLOVER_0_0.S[10791]++;return EMPTY_MAP;}
554 
555         __CLOVER_0_0.S[10792]++;return Collections.unmodifiableMap(_assets);
556     } finally { }}
557 
558     public IAsset getAsset(String name)
559     {try { __CLOVER_0_0.M[2674]++;
560         __CLOVER_0_0.S[10793]++;if ((((_assets == null) && (++__CLOVER_0_0.CT[1865] != 0)) || (++__CLOVER_0_0.CF[1865] == 0))){
561             __CLOVER_0_0.S[10794]++;return null;}
562 
563         __CLOVER_0_0.S[10795]++;return (IAsset) _assets.get(name);
564     } finally { }}
565 
566     public Collection getBindingNames()
567     {try { __CLOVER_0_0.M[2675]++;
568         // If no conainer, i.e. a page, then no bindings.
569 
570         __CLOVER_0_0.S[10796]++;if ((((_container == null) && (++__CLOVER_0_0.CT[1866] != 0)) || (++__CLOVER_0_0.CF[1866] == 0))){
571             __CLOVER_0_0.S[10797]++;return null;}
572 
573         __CLOVER_0_0.S[10798]++;HashSet result = new HashSet();
574 
575         // All the informal bindings go into the bindings Map.
576 
577         __CLOVER_0_0.S[10799]++;if ((((_bindings != null) && (++__CLOVER_0_0.CT[1867] != 0)) || (++__CLOVER_0_0.CF[1867] == 0))){
578             __CLOVER_0_0.S[10800]++;result.addAll(_bindings.keySet());}
579 
580         // Now, iterate over the formal parameters and add the formal parameters
581         // that have a binding.
582 
583         __CLOVER_0_0.S[10801]++;List names = _specification.getParameterNames();
584 
585         __CLOVER_0_0.S[10802]++;int count = names.size();
586 
587         __CLOVER_0_0.S[10803]++;for (int i = 0; (((i < count) && (++__CLOVER_0_0.CT[1868] != 0)) || (++__CLOVER_0_0.CF[1868] == 0)); i++){
588         {
589             __CLOVER_0_0.S[10804]++;String name = (String) names.get(i);
590 
591             __CLOVER_0_0.S[10805]++;if ((((result.contains(name)) && (++__CLOVER_0_0.CT[1869] != 0)) || (++__CLOVER_0_0.CF[1869] == 0))){
592                 __CLOVER_0_0.S[10806]++;continue;}
593 
594             __CLOVER_0_0.S[10807]++;if ((((getBinding(name) != null) && (++__CLOVER_0_0.CT[1870] != 0)) || (++__CLOVER_0_0.CF[1870] == 0))){
595                 __CLOVER_0_0.S[10808]++;result.add(name);}
596         }}
597 
598         __CLOVER_0_0.S[10809]++;return result;
599     } finally { }}
600 
601     /**
602      * Returns a {@link Map}of all bindings for this component. This implementation is expensive,
603      * since it has to merge the disassociated bindings (informal parameters, and parameters without
604      * a JavaBeans property) with the associated bindings (formal parameters with a JavaBeans
605      * property).
606      * 
607      * @since 1.0.5
608      */
609 
610     public Map getBindings()
611     {try { __CLOVER_0_0.M[2676]++;
612         __CLOVER_0_0.S[10810]++;Map result = new HashMap();
613 
614         // Add any informal parameters.
615 
616         __CLOVER_0_0.S[10811]++;if ((((_bindings != null) && (++__CLOVER_0_0.CT[1871] != 0)) || (++__CLOVER_0_0.CF[1871] == 0))){
617             __CLOVER_0_0.S[10812]++;result.putAll(_bindings);}
618 
619         // Now work on the formal parameters
620 
621         __CLOVER_0_0.S[10813]++;Iterator i = _specification.getParameterNames().iterator();
622         __CLOVER_0_0.S[10814]++;while ((((i.hasNext()) && (++__CLOVER_0_0.CT[1872] != 0)) || (++__CLOVER_0_0.CF[1872] == 0))){
623         {
624             __CLOVER_0_0.S[10815]++;String name = (String) i.next();
625 
626             __CLOVER_0_0.S[10816]++;if ((((result.containsKey(name)) && (++__CLOVER_0_0.CT[1873] != 0)) || (++__CLOVER_0_0.CF[1873] == 0))){
627                 __CLOVER_0_0.S[10817]++;continue;}
628 
629             __CLOVER_0_0.S[10818]++;IBinding binding = getBinding(name);
630 
631             __CLOVER_0_0.S[10819]++;if ((((binding != null) && (++__CLOVER_0_0.CT[1874] != 0)) || (++__CLOVER_0_0.CF[1874] == 0))){
632                 __CLOVER_0_0.S[10820]++;result.put(name, binding);}
633         }}
634 
635         __CLOVER_0_0.S[10821]++;return result;
636     } finally { }}
637 
638     /**
639      * Returns a {@link ListenerMap}for the component. A {@link ListenerMap}contains a number of
640      * synthetic read-only properties that implement the {@link IActionListener}interface, but in
641      * fact, cause public instance methods to be invoked.
642      * 
643      * @since 1.0.2
644      */
645 
646     public ListenerMap getListeners()
647     {try { __CLOVER_0_0.M[2677]++;
648         __CLOVER_0_0.S[10822]++;if ((((_listeners == null) && (++__CLOVER_0_0.CT[1875] != 0)) || (++__CLOVER_0_0.CF[1875] == 0))){
649             __CLOVER_0_0.S[10823]++;_listeners = new ListenerMap(this);}
650 
651         __CLOVER_0_0.S[10824]++;return _listeners;
652     } finally { }}
653 
654     /**
655      * Returns the {@link IBeanProvider}for this component. This is lazily created the first time
656      * it is needed.
657      * 
658      * @since 1.0.4
659      */
660 
661     public IBeanProvider getBeans()
662     {try { __CLOVER_0_0.M[2678]++;
663         __CLOVER_0_0.S[10825]++;if ((((_beans == null) && (++__CLOVER_0_0.CT[1876] != 0)) || (++__CLOVER_0_0.CF[1876] == 0))){
664             __CLOVER_0_0.S[10826]++;_beans = new BeanProvider(this);}
665 
666         __CLOVER_0_0.S[10827]++;return _beans;
667     } finally { }}
668 
669     /**
670      * Invoked, as a convienience, from
671      * {@link #finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}. This implemenation
672      * does nothing. Subclasses may override without invoking this implementation.
673      * 
674      * @since 1.0.5
675      */
676 
677     protected void finishLoad()
678     {try { __CLOVER_0_0.M[2679]++;
679     } finally { }}
680 
681     /**
682      * The main method used to render the component. Invokes
683      * {@link #prepareForRender(IRequestCycle)}, then
684      * {@link #renderComponent(IMarkupWriter, IRequestCycle)}.
685      * {@link #cleanupAfterRender(IRequestCycle)}is invoked in a <code>finally</code> block.
686      * <p>
687      * Subclasses should not override this method; instead they will implement
688      * {@link #renderComponent(IMarkupWriter, IRequestCycle)}.
689      * 
690      * @since 2.0.3
691      */
692 
693     public final void render(IMarkupWriter writer, IRequestCycle cycle)
694     {try { __CLOVER_0_0.M[2680]++;
695         __CLOVER_0_0.S[10828]++;try
696         {
697             __CLOVER_0_0.S[10829]++;Tapestry.clearMethodInvocations();
698 
699             __CLOVER_0_0.S[10830]++;prepareForRender(cycle);
700 
701             __CLOVER_0_0.S[10831]++;Tapestry.checkMethodInvocation(PREPAREFORRENDER_METHOD_ID, "prepareForRender()", this);
702 
703             __CLOVER_0_0.S[10832]++;renderComponent(writer, cycle);
704         }
705         finally
706         {
707             __CLOVER_0_0.S[10833]++;Tapestry.clearMethodInvocations();
708 
709             __CLOVER_0_0.S[10834]++;cleanupAfterRender(cycle);
710 
711             __CLOVER_0_0.S[10835]++;Tapestry.checkMethodInvocation(
712                     CLEANUPAFTERRENDER_METHOD_ID,
713                     "cleanupAfterRender()",
714                     this);
715         }
716     } finally { }}
717 
718     /**
719      * Invoked by {@link #render(IMarkupWriter, IRequestCycle)}to prepare the component to render.
720      * This implementation sets JavaBeans properties from matching bound parameters. Subclasses that
721      * override this method must invoke this implementation as well.
722      * 
723      * @since 2.0.3
724      */
725 
726     protected void prepareForRender(IRequestCycle cycle)
727     {try { __CLOVER_0_0.M[2681]++;
728         __CLOVER_0_0.S[10836]++;Tapestry.addMethodInvocation(PREPAREFORRENDER_METHOD_ID);
729 
730         __CLOVER_0_0.S[10837]++;if ((((_parameterManager == null) && (++__CLOVER_0_0.CT[1877] != 0)) || (++__CLOVER_0_0.CF[1877] == 0))){
731         {
732             // Pages inherit from this class too, but pages (by definition)
733             // never have parameters.
734 
735             __CLOVER_0_0.S[10838]++;if ((((getSpecification().isPageSpecification()) && (++__CLOVER_0_0.CT[1878] != 0)) || (++__CLOVER_0_0.CF[1878] == 0))){
736                 __CLOVER_0_0.S[10839]++;return;}
737 
738             __CLOVER_0_0.S[10840]++;_parameterManager = new ParameterManager(this);
739         }}
740 
741         __CLOVER_0_0.S[10841]++;_parameterManager.setParameters(cycle);
742     } finally { }}
743 
744     /**
745      * Invoked by {@link #render(IMarkupWriter, IRequestCycle)}to actually render the component
746      * (with any parameter values already set). This is the method that subclasses must implement.
747      * 
748      * @since 2.0.3
749      */
750 
751     protected abstract void renderComponent(IMarkupWriter writer, IRequestCycle cycle);
752 
753     /**
754      * Invoked by {@link #render(IMarkupWriter, IRequestCycle)}after the component renders, to
755      * clear any parameters back to null (or 0, or false, or whatever the correct default is).
756      * Primarily, this is used to ensure that the component doesn't hold onto any objects that could
757      * otherwise be garbage collected.
758      * <p>
759      * Subclasses may override this implementation, but must also invoke it.
760      * 
761      * @since 2.0.3
762      */
763 
764     protected void cleanupAfterRender(IRequestCycle cycle)
765     {try { __CLOVER_0_0.M[2682]++;
766         __CLOVER_0_0.S[10842]++;Tapestry.addMethodInvocation(CLEANUPAFTERRENDER_METHOD_ID);
767 
768         __CLOVER_0_0.S[10843]++;if ((((_parameterManager != null) && (++__CLOVER_0_0.CT[1879] != 0)) || (++__CLOVER_0_0.CF[1879] == 0))){
769             __CLOVER_0_0.S[10844]++;_parameterManager.resetParameters(cycle);}
770     } finally { }}
771 
772     /** @since 3.0 * */
773 
774     public Messages getMessages()
775     {try { __CLOVER_0_0.M[2683]++;
776         __CLOVER_0_0.S[10845]++;if ((((_strings == null) && (++__CLOVER_0_0.CT[1880] != 0)) || (++__CLOVER_0_0.CF[1880] == 0))){
777             __CLOVER_0_0.S[10846]++;_strings = getPage().getEngine().getComponentMessagesSource().getMessages(this);}
778 
779         __CLOVER_0_0.S[10847]++;return _strings;
780     } finally { }}
781 
782     /**
783      * Obtains the {@link IMessages}for this component (if necessary), and gets the string from it.
784      */
785 
786     public String getString(String key)
787     {try { __CLOVER_0_0.M[2684]++;
788         __CLOVER_0_0.S[10848]++;return getMessages().getMessage(key);
789     } finally { }}
790 
791     public String getMessage(String key)
792     {try { __CLOVER_0_0.M[2685]++;
793         // Invoke the deprecated implementation (for code coverage reasons).
794         // In 3.1, remove getString() and move its implementation
795         // here.
796 
797         __CLOVER_0_0.S[10849]++;return getString(key);
798     } finally { }}
799 
800     /**
801      * Formats a message string, using
802      * {@link IMessages#format(java.lang.String, java.lang.Object[])}.
803      * 
804      * @param key
805      *            the key used to obtain a localized pattern using {@link #getString(String)}
806      * @param arguments
807      *            passed to the formatter
808      * @since 2.2
809      * @deprecated To be removed in 3.1. Use {@link #format(String, Object[])}instead.
810      */
811 
812     public String formatString(String key, Object[] arguments)
813     {try { __CLOVER_0_0.M[2686]++;
814         __CLOVER_0_0.S[10850]++;return getMessages().format(key, arguments);
815     } finally { }}
816 
817     /**
818      * Formats a localized message string, using
819      * {@link IMessages#format(java.lang.String, java.lang.Object[])}.
820      * 
821      * @param key
822      *            the key used to obtain a localized pattern using {@link #getString(String)}
823      * @param arguments
824      *            passed to the formatter
825      * @since 3.0
826      */
827 
828     public String format(String key, Object[] arguments)
829     {try { __CLOVER_0_0.M[2687]++;
830         // SOP: New name invokes deprecated method (consistency and
831         // code coverage); in 3.1 we move the implementation here.
832 
833         __CLOVER_0_0.S[10851]++;return formatString(key, arguments);
834     } finally { }}
835 
836     /**
837      * Convienience method for invoking {@link IMessages#format(String, Object[])}
838      * 
839      * @since 2.2
840      * @deprecated To be removed in 3.1. Use {@link #format(String, Object)}instead.
841      */
842 
843     public String formatString(String key, Object argument)
844     {try { __CLOVER_0_0.M[2688]++;
845         __CLOVER_0_0.S[10852]++;return getMessages().format(key, argument);
846     } finally { }}
847 
848     /**
849      * Convienience method for invoking {@link IMessages#format(String, Object)}
850      * 
851      * @since 3.0
852      */
853 
854     public String format(String key, Object argument)
855     {try { __CLOVER_0_0.M[2689]++;
856         __CLOVER_0_0.S[10853]++;return formatString(key, argument);
857     } finally { }}
858 
859     /**
860      * Convienience method for invoking {@link IMessages#format(String, Object, Object)}.
861      * 
862      * @since 2.2
863      * @deprecated To be removed in 3.1. Use {@link #format(String, Object, Object)}instead.
864      */
865 
866     public String formatString(String key, Object argument1, Object argument2)
867     {try { __CLOVER_0_0.M[2690]++;
868         __CLOVER_0_0.S[10854]++;return getMessages().format(key, argument1, argument2);
869     } finally { }}
870 
871     /**
872      * Convienience method for invoking {@link IMessages#format(String, Object, Object)}.
873      * 
874      * @since 3.0
875      */
876 
877     public String format(String key, Object argument1, Object argument2)
878     {try { __CLOVER_0_0.M[2691]++;
879         __CLOVER_0_0.S[10855]++;return formatString(key, argument1, argument2);
880     } finally { }}
881 
882     /**
883      * Convienience method for {@link IMessages#format(String, Object, Object, Object)}.
884      * 
885      * @since 2.2
886      * @deprecated To be removed in 3.1. Use {@link #format(String, Object, Object, Object)}
887      *             instead.
888      */
889 
890     public String formatString(String key, Object argument1, Object argument2, Object argument3)
891     {try { __CLOVER_0_0.M[2692]++;
892         __CLOVER_0_0.S[10856]++;return getMessages().format(key, argument1, argument2, argument3);
893     } finally { }}
894 
895     /**
896      * Convienience method for {@link IMessages#format(String, Object, Object, Object)}.
897      * 
898      * @since 3.0
899      */
900 
901     public String format(String key, Object argument1, Object argument2, Object argument3)
902     {try { __CLOVER_0_0.M[2693]++;
903         __CLOVER_0_0.S[10857]++;return formatString(key, argument1, argument2, argument3);
904     } finally { }}
905 
906     public INamespace getNamespace()
907     {try { __CLOVER_0_0.M[2694]++;
908         __CLOVER_0_0.S[10858]++;return _namespace;
909     } finally { }}
910 
911     public void setNamespace(INamespace namespace)
912     {try { __CLOVER_0_0.M[2695]++;
913         __CLOVER_0_0.S[10859]++;_namespace = namespace;
914     } finally { }}
915 
916     /**
917      * Returns the body of the component, the element (which may be static HTML or components) that
918      * the component immediately wraps. May return null. Do not modify the returned array. The array
919      * may be padded with nulls.
920      * 
921      * @since 2.3
922      * @see #getBodyCount()
923      */
924 
925     public IRender[] getBody()
926     {try { __CLOVER_0_0.M[2696]++;
927         __CLOVER_0_0.S[10860]++;return _body;
928     } finally { }}
929 
930     /**
931      * Returns the active number of elements in the the body, which may be zero.
932      * 
933      * @since 2.3
934      * @see #getBody()
935      */
936 
937     public int getBodyCount()
938     {try { __CLOVER_0_0.M[2697]++;
939         __CLOVER_0_0.S[10861]++;return _bodyCount;
940     } finally { }}
941 
942     /**
943      * Empty implementation of
944      * {@link org.apache.tapestry.event.PageRenderListener#pageEndRender(PageEvent)}. This allows
945      * classes to implement {@link org.apache.tapestry.event.PageRenderListener}and only implement
946      * the {@link org.apache.tapestry.event.PageRenderListener#pageBeginRender(PageEvent)}method.
947      * 
948      * @since 3.0
949      */
950 
951     public void pageEndRender(PageEvent event)
952     {try { __CLOVER_0_0.M[2698]++;
953     } finally { }}
954 
955     /**
956      * Sets a property of a component.
957      * 
958      * @see IComponent
959      * @since 3.0
960      */
961     public void setProperty(String propertyName, Object value)
962     {try { __CLOVER_0_0.M[2699]++;
963         __CLOVER_0_0.S[10862]++;OgnlUtils.set(propertyName, this, value);
964     } finally { }}
965 
966     /**
967      * Gets a property of a component.
968      * 
969      * @see IComponent
970      * @since 3.0
971      */
972     public Object getProperty(String propertyName)
973     {try { __CLOVER_0_0.M[2700]++;
974         __CLOVER_0_0.S[10863]++;return OgnlUtils.get(propertyName, this);
975     } finally { }}
976 }