001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.structure;
016:
017: import java.util.Locale;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.tapestry.ComponentResources;
021: import org.apache.tapestry.Link;
022: import org.apache.tapestry.runtime.Component;
023: import org.apache.tapestry.runtime.PageLifecycleListener;
024:
025: /**
026: * Represents a unique page within the application. Pages are part of the <em>internal</em>
027: * structure of a Tapestry application; end developers who refer to "page" are really referring to
028: * the {@link #getRootComponent() root component} of the actual page.
029: * <p>
030: * One of the most important aspects of a Page is that it <em>does not</em> have to be coded in a
031: * thread-safe manner. Pages are always accessed within a single thread, associated with a single
032: * incoming request.
033: * <p>
034: * The Page object is never visible to end-user code. The page also exists to provide a kind of
035: * service to components embedded (directly or indirectly) within the page.
036: */
037: public interface Page {
038: /**
039: * Returns the short, logical name for the page.
040: */
041: String getLogicalName();
042:
043: /**
044: * The locale for which the page is localized. This is set when the page is created and does not
045: * change.
046: */
047: Locale getLocale();
048:
049: /**
050: * Invoked during page construction time to connect the page's root component to the page
051: * instance.
052: */
053: void setRootElement(ComponentPageElement component);
054:
055: /**
056: * The root component of the page. This is the wrapper around the end developer's view of the
057: * page.
058: */
059: ComponentPageElement getRootElement();
060:
061: /**
062: * The root component of the page. A convenience over invoking getRootElement().getComponent().
063: */
064: Component getRootComponent();
065:
066: /**
067: * Invoked to inform the page that it is being detached from the current request. This occurs
068: * just before the page is returned to the page pool.
069: * <p>
070: * A page may be clean or dirty. A page is dirty if its dirty count is greater than zero
071: * (meaning that, during the render of the page, some components did not fully render), or if
072: * any of its listeners throw an exception from containingPageDidDetech().
073: * <p>
074: * The page pool should discard pages that are dirty, rather than store them into the pool.
075: *
076: * @return true if the page is "dirty", false otherwise
077: * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidDetach()
078: */
079: boolean detached();
080:
081: /**
082: * Invoked to inform the page that it is attached to the current request. This occurs when a
083: * page is first referenced within a request. If the page was created from scratch for this
084: * request, the call to {@link #loaded()} will preceded the call to {@link #attached()}.
085: */
086:
087: void attached();
088:
089: /**
090: * Inform the page that it is now completely loaded.
091: *
092: * @see org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()
093: */
094:
095: void loaded();
096:
097: /**
098: * Adds a listener that is notified of large scale page events.
099: */
100: void addLifecycleListener(PageLifecycleListener listener);
101:
102: /** Returns the log of the root component element. */
103: Log getLog();
104:
105: /**
106: * Retrieves a component element by its nested id (a sequence of simple ids, separated by dots).
107: * A nested id of '' (the empty string) returns the root element of the page.
108: *
109: * @throws IllegalArgumentException
110: * if the nestedId does not correspond to a component
111: */
112: ComponentPageElement getComponentElementByNestedId(String nestedId);
113:
114: /**
115: * Creates a link that will trigger behavior in a component within the page.
116: *
117: * @param element
118: * @param action
119: * @param forForm
120: * @param context
121: * @return
122: */
123: Link createActionLink(ComponentPageElement element, String action,
124: boolean forForm, Object... context);
125:
126: /**
127: * Creates a link to the named page.
128: *
129: * @param pageName
130: * the logical name of the page
131: * @param override
132: * if true, the provided context is used even if empty
133: * @param context
134: * optional activation context for the page (if not provided, it is generated from
135: * the page itself)
136: */
137: Link createPageLink(String pageName, boolean override,
138: Object... context);
139:
140: /**
141: * Posts a change to a persistent field.
142: *
143: * @param resources
144: * the component resources for the component or mixin containing the field whose
145: * value changed
146: * @param fieldName
147: * the name of the field
148: * @param newValue
149: * the new value for the field
150: */
151: void persistFieldChange(ComponentResources resources,
152: String fieldName, Object newValue);
153:
154: /**
155: * Gets a change for a field within the component.
156: *
157: * @param element
158: * the element for which a persistent field value is required
159: * @param fieldName
160: * the name of the persistent field
161: * @return the value, or null if no value is stored
162: */
163: Object getFieldChange(ComponentPageElement element, String fieldName);
164:
165: /**
166: * Called as a component initially starts to render itself. This is used to check for the cases
167: * where a component causes a runtime exception that aborts the render early, leaving the page
168: * in an invalid state.
169: */
170: void incrementDirtyCount();
171:
172: /** Called as a component finishes rendering itself. */
173: void decrementDirtyCount();
174: }
|