01: /*
02: * Created on Jul 27, 2005
03: */
04: package uk.org.ponder.rsf.components;
05:
06: import uk.org.ponder.rsf.components.decorators.DecoratorList;
07: import uk.org.ponder.rsf.components.decorators.UIDecorator;
08: import uk.org.ponder.rsf.util.RSFUtil;
09:
10: /**
11: * UIComponent is the base of the entire RSF component hierarchy. Components
12: * derived from this class may either be containers derived from UIContainer,
13: * or else leaf components peering with target dialect tags.
14: * Note that Components form a containment hierarchy ONLY to allow nested
15: * repetitive domains. This class is mutually referential with UIContainer.
16: * @author Antranig Basman (antranig@caret.cam.ac.uk)
17: *
18: */
19: public class UIComponent {
20: /** This ID corresponds to the rsf:id in the view template, and is parsed
21: * by use of the class SplitID.
22: */
23: public String ID;
24: // fullid is the full path to this component
25: // structure: ID1-prefix:ID1-suffix:localID1:ID2-prefix:ID2-suffix:localID2:etc.
26: private String fullID;
27:
28: /** The algorithm used here must deterministically generate a string ID
29: * globally unique within the containing component tree (the View), by
30: * appending path components derived from IDs and local IDs found at each
31: * level of UIContainer. This algorithm should be "accessible" to simple
32: * environments such as XSLTs since they will need to operate it to generate
33: * inter-component references within a view (for example to express any
34: * EL dependencies).
35: * <p>
36: * The structure of the ID forms colon-separated "triples", one for each
37: * container in the path, ending with the rsf:id of any leaf component, e.g.
38: * ID1-prefix:ID1-suffix:localID1:ID2-prefix:ID2-suffix:localID2:etc.
39: */
40: public String getFullID() {
41: if (fullID == null) {
42: fullID = RSFUtil.computeFullID(this );
43: }
44: return fullID;
45: }
46:
47: /** Updates the full ID of this component with the supplied value. This
48: * is an "emergency" method to be used only as a last resort. Within RSF
49: * it is necessary to ensure that UIBound components arising as direct children
50: * of "composite" parents can have their IDs set correctly before value
51: * fixup.
52: */
53: public void updateFullID(String fullID) {
54: this .fullID = fullID;
55: }
56:
57: /** The containing parent of this component, or <code>null</code> for the
58: * UIContainer representing the view root.
59: */
60: public UIContainer parent;
61:
62: /** A list of "decorators" which alter the rendering behaviour of this
63: * component, orthogonal to its binding behaviour. Usually <code>null</code>
64: */
65: public DecoratorList decorators;
66:
67: /** Add the supplied decorator to the list for this component, initialising
68: * the list if necessary.
69: */
70: public UIComponent decorate(UIDecorator decorator) {
71: if (decorators == null) {
72: decorators = new DecoratorList();
73: }
74: decorators.add(decorator);
75: return this;
76: }
77: }
|