KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > jsfext > layout > LayoutViewRoot


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.tools.jsfext.layout;
24
25 import com.sun.enterprise.tools.jsfext.component.ComponentUtil;
26 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutComponent;
27 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutDefinition;
28 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutElement;
29 import com.sun.enterprise.tools.jsfext.layout.LayoutDefinitionManager;
30 import com.sun.enterprise.tools.jsfext.util.LogUtil;
31
32 import javax.faces.component.UIComponent;
33 import javax.faces.component.UIViewRoot;
34 import javax.faces.context.ExternalContext;
35 import javax.faces.context.FacesContext;
36
37
38 /**
39  * <p> This is a <code>UIViewRoot</code> implemenation that allows the
40  * <code>UIComponent</code> tree to be defined by a
41  * {@link LayoutDefinition}. This implementation is used by the
42  * {@link ViewHandler} implementation in this same package. It is
43  * expected that {@link #setLayoutDefinitionKey(String)} will be invoked
44  * soon after creation. This key will be resolved by the configured
45  * {@link LayoutDefinitionManager} to locate the {@link LayoutDefinition}
46  * which defines the <code>UIComponent</code> tree.</p>
47  *
48  * @author Ken Paulsen (ken.paulsen@sun.com)
49  */

50 public class LayoutViewRoot extends UIViewRoot {
51
52     /**
53      * <p> Constructor.</p>
54      */

55     public LayoutViewRoot() {
56     super();
57     }
58
59     /**
60      * <p> This method enables the decode event to work for pages.</p>
61      *
62      * <p> This method checks for "LavaChannel" requests and treats them
63      * differently than normal requests. It only decodes the targeted
64      * UIComponent (and its children), then invokes processApplication(),
65      * and finally renders a partial response (rendering change is
66      * actually handled by LayoutViewHandler).</p>
67      *
68      * <p> When decoding template-based components, this is handled by the
69      * TemplateRenderer. However, when dealing with pages, this is done
70      * here (TemplateRenderer is not involved to fire handlers).</p>
71      *
72      * <p> This method continues to delegate to the superclass after invoking
73      * any registered handlers.</p>
74      */

75     public void processDecodes(FacesContext context) {
76
77 // BEGIN EXPERIMENTAL CODE...
78
ExternalContext extCtx = context.getExternalContext();
79     String JavaDoc targetId = extCtx.getRequestParameterMap().get(LayoutViewHandler.LAVA_CHANNEL_KEY);
80     if ((targetId != null) && !targetId.equals("")) {
81         // Detected "LavaChannel" Request
82
// This request will only process a sub-tree of the UIComponent
83
// tree and return the cooresponding partial HTML
84

85         // First find the LavaChannel target
86
UIComponent target = findComponent(":"+targetId);
87         if (target == null) {
88         // FIXME: Log a warning message!
89
// FIXME: Rework this so that the following 6 lines are duplicated
90
LayoutDefinition def = getLayoutDefinition(context);
91         if (def != null) {
92             def.decode(context, this);
93         }
94         super.processDecodes(context);
95         return;
96         }
97         extCtx.getRequestMap().put(LayoutViewHandler.LAVA_CHANNEL_TARGET_KEY, target);
98
99         // Process sub-tree (similar to immedate, no validation/update)
100
target.processDecodes(context);
101         processApplication(context);
102
103         // Mark the context that the next phase should be RenderResponse
104
context.renderResponse();
105     } else {
106     // END EXPERIMENTAL CODE...
107

108         LayoutDefinition def = getLayoutDefinition(context);
109         if (def != null) {
110         def.decode(context, this);
111         }
112         super.processDecodes(context);
113     }
114     }
115
116     /**
117      * <p> This method provides the ability to obtain a "child"
118      * <code>UIComponent</code> from this <code>UIViewRoot</code>.</p>
119      *
120      * @param context The <code>FacesContext</code>.
121      * @param id The <code>id</code> of <code>UIComponent</code> child.
122      *
123      * @return The requested <code>UIComponent</code> or null if not found.
124      */

125     public UIComponent getChild(FacesContext context, String JavaDoc id) {
126     if ((id == null) || (id.trim().equals(""))) {
127         // No id, no LayoutComponent, nothing we can do.
128
return null;
129     }
130
131     // We have an id, use it to search for an already-created child
132
UIComponent childComponent = ComponentUtil.findChild(this, id, id);
133     if (childComponent != null) {
134         return childComponent;
135     }
136
137     // If we're still here, then we need to create it... hopefully we have
138
// a LayoutComponent to tell us how to do this!
139
LayoutDefinition ld = getLayoutDefinition(context);
140     if (ld == null) {
141         // No LayoutDefinition to tell us how to create it... return null
142
return null;
143     }
144
145     // Attempt to find a LayoutComponent matching the id
146
LayoutElement elt =
147         LayoutDefinition.getChildLayoutElementById(context, id, ld, this);
148
149     // Create the child from the LayoutComponent
150
return getChild(context, (LayoutComponent) elt);
151     }
152
153     /**
154      * <p> This method provides the ability to obtain a "child"
155      * <code>UIComponent</code> from this <code>UIViewRoot</code>. If
156      * the child does not already exist, it will be created using the
157      * given {@link LayoutComponent} descriptor.</p>
158      *
159      * @param context The <code>FacesContext</code>.
160      * @param descriptor The {@link LayoutComponent} for the
161      * <code>UIComponent</code> child.
162      *
163      * @return The requested <code>UIComponent</code>.
164      *
165      * @throws IllegalArgumentException if descriptor is null.
166      */

167     public UIComponent getChild(FacesContext context, LayoutComponent descriptor) {
168     UIComponent childComponent = null;
169
170     // Sanity check
171
if (descriptor == null) {
172         throw new IllegalArgumentException JavaDoc("The LayoutComponent is null!");
173     }
174
175     // First pull off the id from the descriptor
176
String JavaDoc id = descriptor.getId(context, this);
177     if ((id != null) && !(id.trim().equals(""))) {
178         // We have an id, use it to search for an already-created child
179
childComponent = ComponentUtil.findChild(this, id, id);
180         if (childComponent != null) {
181         return childComponent;
182         }
183     }
184
185     // No id, or the component hasn't been created. In either case, we
186
// create a new component (moral: always have an id)
187

188     // Invoke "beforeCreate" handlers
189
descriptor.beforeCreate(context, this);
190
191     // Create UIComponent
192
childComponent =
193         ComponentUtil.createChildComponent(context, descriptor, this);
194
195     // Invoke "afterCreate" handlers
196
descriptor.afterCreate(context, childComponent);
197
198     // Return the newly created UIComponent
199
return childComponent;
200     }
201
202     /**
203      * <p> Returns the {@link LayoutDefinition}. If the
204      * {@link LayoutDefinition} has not already be retrieved, it will be
205      * found using the set {@link LayoutDefinition} "key". If the key is
206      * not yet set, this method will return null.</p>
207      *
208      * @param context The <code>FacesContext</code>.
209      *
210      * @return The {@link LayoutDefinition} for this <code>UIViewRoot</code>.
211      */

212     public LayoutDefinition getLayoutDefinition(FacesContext context) {
213     // Make sure we don't already have it...
214
if (_layoutDefinition != null) {
215         return _layoutDefinition;
216     }
217
218     // Get the LayoutDefinitionManager key
219
String JavaDoc key = getLayoutDefinitionKey();
220     if (key == null) {
221         return null;
222     }
223
224     // Get the LayoutDefinitionManager
225
LayoutDefinitionManager ldm =
226         LayoutDefinitionManager.getManager(context);
227
228     // Save the LayoutDefinition for future calls to this method
229
try {
230         _layoutDefinition = ldm.getLayoutDefinition(key);
231     } catch (java.io.IOException JavaDoc ex) {
232         if (LogUtil.configEnabled(this)) {
233         LogUtil.config(
234             "Unable to get LayoutDefinition for '" + key + "'.");
235         }
236     }
237
238     // Return the LayoutDefinition (if found)
239
return _layoutDefinition;
240     }
241
242     /**
243      * <p> Accessor method for the <code>LayoutDefintionKey</code>.</p>
244      *
245      * @return The {@link LayoutDefinition} key.
246      */

247     public String JavaDoc getLayoutDefinitionKey() {
248     return _ldmKey;
249     }
250
251     /**
252      * <p> Setter for the <code>LayoutDefintionKey</code>.</p>
253      *
254      * @param The {@link LayoutDefinition} key.
255      */

256     public void setLayoutDefinitionKey(String JavaDoc key) {
257     _ldmKey = key;
258     }
259
260     /**
261      * <p> This method saves the state for this component. It relies on the
262      * superclass to save its own sate, this method will invoke
263      * super.saveState().</p>
264      *
265      * @param context The <code>FacesContext</code>.
266      *
267      * @return The serialized state.
268      */

269     public Object JavaDoc saveState(FacesContext context) {
270     Object JavaDoc [] values = new Object JavaDoc[2];
271     values[0] = super.saveState(context);
272     values[1] = _ldmKey;
273     return values;
274     }
275
276     /**
277      * <p> This method restores the state for this component. It will invoke
278      * the superclass to restore its state.</p>
279      *
280      * @param context The <code>FacesContext</code>.
281      * @param state The serialized state.
282      */

283     public void restoreState(FacesContext context, Object JavaDoc state) {
284     Object JavaDoc [] values = (Object JavaDoc[]) state;
285     super.restoreState(context, values[0]);
286     _ldmKey = (java.lang.String JavaDoc) values[1];
287     }
288
289
290     private String JavaDoc _ldmKey = null;
291     private transient LayoutDefinition _layoutDefinition = null;
292 }
293
Popular Tags